Source Code Cross Referenced for JEntityFactory.java in  » J2EE » JOnAS-4.8.6 » org » objectweb » jonas_ejb » container » 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 » JOnAS 4.8.6 » org.objectweb.jonas_ejb.container 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /**
0002:         * JOnAS: Java(TM) Open Application Server
0003:         * Copyright (C) 1999 Bull S.A.
0004:         * Contact: jonas-team@objectweb.org
0005:         *
0006:         * This library is free software; you can redistribute it and/or
0007:         * modify it under the terms of the GNU Lesser General Public
0008:         * License as published by the Free Software Foundation; either
0009:         * version 2.1 of the License, or any later version.
0010:         *
0011:         * This library is distributed in the hope that it will be useful,
0012:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
0013:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0014:         * Lesser General Public License for more details.
0015:         *
0016:         * You should have received a copy of the GNU Lesser General Public
0017:         * License along with this library; if not, write to the Free Software
0018:         * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
0019:         * USA
0020:         *
0021:         * --------------------------------------------------------------------------
0022:         * $Id: JEntityFactory.java 9860 2006-11-23 16:40:22Z durieuxp $
0023:         * --------------------------------------------------------------------------
0024:         */package org.objectweb.jonas_ejb.container;
0025:
0026:        import java.io.Serializable;
0027:        import java.util.ArrayList;
0028:        import java.util.Collection;
0029:        import java.util.Date;
0030:        import java.util.HashMap;
0031:        import java.util.Iterator;
0032:        import java.util.LinkedList;
0033:        import java.util.List;
0034:        import java.util.ListIterator;
0035:
0036:        import javax.ejb.EJBException;
0037:        import javax.ejb.EntityBean;
0038:        import javax.ejb.FinderException;
0039:        import javax.ejb.Timer;
0040:        import javax.ejb.TimerService;
0041:        import javax.naming.Context;
0042:        import javax.naming.NamingException;
0043:        import javax.transaction.RollbackException;
0044:        import javax.transaction.SystemException;
0045:        import javax.transaction.Transaction;
0046:
0047:        import org.objectweb.jonas_ejb.deployment.api.EntityDesc;
0048:        import org.objectweb.jonas_ejb.deployment.api.EntityJdbcCmp1Desc;
0049:        import org.objectweb.jonas_ejb.deployment.api.EntityJdbcCmp2Desc;
0050:
0051:        import org.objectweb.util.monolog.api.BasicLevel;
0052:
0053:        /**
0054:         * This class is a factory for an Entity Bean. It is responsible for
0055:         * - managing Home and LocalHome.
0056:         * - managing a pool of instances/contexts
0057:         * - keeping the list of PKs and the associated JEntitySwitch's
0058:         * - keeping the JNDI context for this component (java:comp/env)
0059:         * @author Philippe Coq, Philippe Durieux
0060:         */
0061:        /**
0062:         * @author coqp
0063:         *
0064:         * TODO To change the template for this generated type comment go to
0065:         * Window - Preferences - Java - Code Style - Code Templates
0066:         */
0067:        public class JEntityFactory extends JFactory implements  TimerService {
0068:
0069:            /**
0070:             * optional home
0071:             */
0072:            protected JEntityHome home = null;
0073:
0074:            /**
0075:             * @return the home if it exists
0076:             */
0077:            public JHome getHome() {
0078:                return home;
0079:            }
0080:
0081:            /**
0082:             * optional local home
0083:             */
0084:            protected JEntityLocalHome localhome = null;
0085:
0086:            /**
0087:             * @return the local home if it exists
0088:             */
0089:            public JLocalHome getLocalHome() {
0090:                return localhome;
0091:            }
0092:
0093:            /**
0094:             * lock policy
0095:             */
0096:            protected int lockPolicy;
0097:
0098:            /**
0099:             * @return lockPolicy
0100:             */
0101:            public int getLockPolicy() {
0102:                return lockPolicy;
0103:            }
0104:
0105:            /**
0106:             * enable the prefetch for CMP2 bean
0107:             */
0108:            protected boolean prefetch = false;
0109:
0110:            /**
0111:             * @return true if prefetch enable
0112:             */
0113:            public boolean isPrefetch() {
0114:                return prefetch;
0115:            }
0116:
0117:            /**
0118:             * True if CMP2 container
0119:             */
0120:            protected boolean cmp2 = true;
0121:
0122:            /**
0123:             * @return true if CMP2 container
0124:             */
0125:            public boolean isCMP2() {
0126:                return cmp2;
0127:            }
0128:
0129:            /**
0130:             * shared if the EJB container is not the only one to modify
0131:             * the bean state on the database, or if a cluster of container
0132:             * access the bean concurrently.
0133:             */
0134:            protected boolean shared = false;
0135:
0136:            /**
0137:             * @return true if shared
0138:             */
0139:            public boolean isShared() {
0140:                return shared;
0141:            }
0142:
0143:            /**
0144:             * reentrant if instance can be used concurrently
0145:             */
0146:            protected boolean reentrant;
0147:
0148:            /**
0149:             * @return true if reentrant
0150:             */
0151:            public boolean isReentrant() {
0152:                return reentrant;
0153:            }
0154:
0155:            /**
0156:             * @return true if the bean is shared
0157:             */
0158:            public boolean getSelectForUpdate() {
0159:                return shared
0160:                        && lockPolicy == EntityDesc.LOCK_CONTAINER_SERIALIZED_TRANSACTED;
0161:                // In case of database lock-policy, setting the selectForUpdate option
0162:                // leads sometimes to deadlocks, at least on postgresql.
0163:                //return shared;
0164:            }
0165:
0166:            /**
0167:             * Number of seconds before reading again instances for read-only.
0168:             */
0169:            protected int readTimeout; // sec.
0170:
0171:            /**
0172:             * @return read timeout in sec.
0173:             */
0174:            public int getReadTimeout() {
0175:                return readTimeout;
0176:            }
0177:
0178:            /**
0179:             * Number of seconds before releasing objects when not used.
0180:             */
0181:            private int inactivityTimeout; // sec.
0182:
0183:            /**
0184:             * @return inactivity timeout in sec.
0185:             */
0186:            public int getInactivityTimeout() {
0187:                return inactivityTimeout;
0188:            }
0189:
0190:            /**
0191:             * Set the inactivity timeout (jonas admin)
0192:             * Not used today
0193:             */
0194:            public void setInactivityTimeout(int i) {
0195:                inactivityTimeout = i;
0196:            }
0197:
0198:            /**
0199:             * Number of seconds before loocking for deadlock when stuck
0200:             */
0201:            private int deadlockTimeout; // sec.
0202:
0203:            /**
0204:             * @return deadlock timeout in sec.
0205:             */
0206:            public int getDeadlockTimeout() {
0207:                return deadlockTimeout;
0208:            }
0209:
0210:            /**
0211:             * Set the deadlock timeout (jonas admin)
0212:             * Not used today
0213:             */
0214:            public void setDeadlockTimeout(int i) {
0215:                deadlockTimeout = i;
0216:            }
0217:
0218:            /**
0219:             * Number of seconds before storing objects (CS policy only)
0220:             */
0221:            private int passivationTimeout; // sec.
0222:
0223:            /**
0224:             * @return passivation timeout in sec.
0225:             */
0226:            public int getPassivationTimeout() {
0227:                return passivationTimeout;
0228:            }
0229:
0230:            /**
0231:             * Set the passivation timeout (jonas admin)
0232:             * Not used today
0233:             */
0234:            public void setPassivationTimeout(int i) {
0235:                TraceEjb.logger.log(BasicLevel.WARN, ejbname);
0236:                passivationTimeout = i;
0237:            }
0238:
0239:            /**
0240:             * Datasource in case of CMP
0241:             */
0242:            protected Object datasource = null;
0243:
0244:            /**
0245:             * datasource name
0246:             */
0247:            String dsname = null;
0248:
0249:            /**
0250:             * @return the Datasource used for CMP
0251:             */
0252:            public Object getDataSource() {
0253:                if (datasource == null) {
0254:                    TraceEjb.logger.log(BasicLevel.ERROR, ejbname
0255:                            + ": datasource not defined");
0256:                }
0257:                return datasource;
0258:            }
0259:
0260:            /**
0261:             * Dummy method that defines the FinderException in the throws clause
0262:             * to can catch this exception in any case in the JentityHome.vm
0263:             * @param dummy if true do nothing, else throw the FinderException
0264:             * @throws FinderException if dummy is false
0265:             */
0266:            public void dummyFinderException(boolean dummy)
0267:                    throws FinderException {
0268:                if (!dummy) {
0269:                    throw new FinderException("dummy exception !!!");
0270:                }
0271:            }
0272:
0273:            // -----------------------------------------------------------------
0274:            // Start - Stop
0275:            // -----------------------------------------------------------------
0276:
0277:            /**
0278:             * constructor must be without parameters (required by Jorm)
0279:             */
0280:            public JEntityFactory() {
0281:                TraceEjb.interp.log(BasicLevel.DEBUG, "");
0282:            }
0283:
0284:            /**
0285:             * Init this object
0286:             * @param dd the deployment descriptor
0287:             * @param cont the Container
0288:             */
0289:            public void init(EntityDesc dd, JContainer cont) {
0290:                super .init(dd, cont);
0291:                reentrant = dd.isReentrant();
0292:                shared = dd.isShared();
0293:                lockPolicy = dd.getLockPolicy();
0294:                prefetch = dd.isPrefetch();
0295:                hardLimit = dd.isHardLimit();
0296:
0297:                // Check lock-policy compatible with shared and prefetch flags
0298:                switch (lockPolicy) {
0299:                case EntityDesc.LOCK_CONTAINER_READ_UNCOMMITTED:
0300:                    if (prefetch) {
0301:                        prefetch = false;
0302:                        TraceEjb.logger
0303:                                .log(BasicLevel.WARN,
0304:                                        "prefetch flag forced to false, with CRU lock policy");
0305:                    }
0306:                    TraceEjb.logger
0307:                            .log(BasicLevel.WARN,
0308:                                    "This policy (CRU) is deprecated. Use CRW instead!");
0309:                    break;
0310:                case EntityDesc.LOCK_CONTAINER_READ_WRITE:
0311:                    if (prefetch) {
0312:                        prefetch = false;
0313:                        TraceEjb.logger
0314:                                .log(BasicLevel.WARN,
0315:                                        "prefetch flag forced to false with CRW lock policy");
0316:                    }
0317:                    if (shared) {
0318:                        shared = false;
0319:                        TraceEjb.logger
0320:                                .log(BasicLevel.WARN,
0321:                                        "shared flag forced to false with CRW lock policy");
0322:                    }
0323:                    break;
0324:                case EntityDesc.LOCK_CONTAINER_SERIALIZED:
0325:                    if (shared) {
0326:                        TraceEjb.logger
0327:                                .log(BasicLevel.WARN,
0328:                                        "shared flag should be set to false with CS policy");
0329:                        TraceEjb.logger.log(BasicLevel.WARN,
0330:                                "Consider switching to the new CST policy");
0331:                    }
0332:                    break;
0333:                case EntityDesc.LOCK_DATABASE:
0334:                    if (!shared) {
0335:                        shared = true;
0336:                        TraceEjb.logger.log(BasicLevel.WARN,
0337:                                "shared flag forced to true with DB policy");
0338:                    }
0339:                    break;
0340:                }
0341:                inactivityTimeout = dd.getInactivityTimeout();
0342:                passivationTimeout = dd.getPassivationTimeout();
0343:                deadlockTimeout = dd.getDeadlockTimeout();
0344:                readTimeout = dd.getReadTimeout();
0345:                setMaxWaitTime(dd.getMaxWaitTime());
0346:
0347:                // Finds the DataSource associated to the bean
0348:                // Useful for Entity with Container Managed Persistence.
0349:                if (dd instanceof  EntityJdbcCmp1Desc) {
0350:                    cmp2 = false;
0351:                    dsname = ((EntityJdbcCmp1Desc) dd).getDatasourceJndiName();
0352:                    if (dsname != null) {
0353:                        try {
0354:                            datasource = getInitialContext().lookup(dsname);
0355:                        } catch (NamingException e) {
0356:                            String err = dsname
0357:                                    + " is not known by the EJB server.";
0358:                            TraceEjb.logger.log(BasicLevel.ERROR, err, e);
0359:                            throw new EJBException(err, e);
0360:                        }
0361:                    }
0362:                    if (lockPolicy == EntityDesc.LOCK_CONTAINER_READ_WRITE) {
0363:                        throw new EJBException(
0364:                                "Cannot use CONTAINER_READ_WRITE with a CMP1 bean");
0365:                    }
0366:                }
0367:
0368:                if (dd instanceof  EntityJdbcCmp2Desc) {
0369:                    cmp2 = true;
0370:                    dsname = ((EntityJdbcCmp2Desc) dd).getDatasourceJndiName();
0371:                    if (dsname != null) {
0372:                        try {
0373:                            datasource = getInitialContext().lookup(dsname);
0374:                        } catch (NamingException e) {
0375:                            String err = dsname
0376:                                    + " is not known by the EJB server.";
0377:                            TraceEjb.logger.log(BasicLevel.ERROR, err);
0378:                            throw new EJBException(err, e);
0379:                        }
0380:                    }
0381:                }
0382:
0383:                // Create the Home if defined in DD
0384:                Class homeclass = null;
0385:                String clname = dd.getFullWrpHomeName();
0386:                if (clname != null) {
0387:                    try {
0388:                        homeclass = cont.getClassLoader().loadClass(clname);
0389:                    } catch (ClassNotFoundException e) {
0390:                        throw new EJBException(ejbname + "Cannot load "
0391:                                + clname, e);
0392:                    }
0393:                    if (TraceEjb.isDebugIc()) {
0394:                        TraceEjb.interp.log(BasicLevel.DEBUG, ejbname + ": "
0395:                                + clname + " loaded");
0396:                    }
0397:                    try {
0398:                        // new JEntityHome(dd, this)
0399:                        int nbp = 2;
0400:                        Class[] ptype = new Class[nbp];
0401:                        Object[] pobj = new Object[nbp];
0402:                        ptype[0] = org.objectweb.jonas_ejb.deployment.api.EntityDesc.class;
0403:                        pobj[0] = (Object) dd;
0404:                        ptype[1] = org.objectweb.jonas_ejb.container.JEntityFactory.class;
0405:                        pobj[1] = (Object) this ;
0406:                        home = (JEntityHome) homeclass.getConstructor(ptype)
0407:                                .newInstance(pobj);
0408:                    } catch (Exception e) {
0409:                        throw new EJBException(
0410:                                ejbname + " Cannot create home ", e);
0411:                    }
0412:
0413:                    // register it in JNDI
0414:                    try {
0415:                        home.register();
0416:                    } catch (Exception e) {
0417:                        throw new EJBException(ejbname
0418:                                + " Cannot register home ", e);
0419:                    }
0420:                }
0421:
0422:                // Create the LocalHome if defined in DD
0423:                clname = dd.getFullWrpLocalHomeName();
0424:                if (clname != null) {
0425:                    try {
0426:                        homeclass = cont.getClassLoader().loadClass(clname);
0427:                    } catch (ClassNotFoundException e) {
0428:                        TraceEjb.logger.log(BasicLevel.ERROR, ejbname
0429:                                + " cannot load " + clname);
0430:                        throw new EJBException("Cannot load " + clname, e);
0431:                    }
0432:                    if (TraceEjb.isDebugIc()) {
0433:                        TraceEjb.interp.log(BasicLevel.DEBUG, ejbname + ": "
0434:                                + clname + " loaded");
0435:                    }
0436:                    try {
0437:                        // new JEntityLocalHome(dd, this)
0438:                        int nbp = 2;
0439:                        Class[] ptype = new Class[nbp];
0440:                        Object[] pobj = new Object[nbp];
0441:                        ptype[0] = org.objectweb.jonas_ejb.deployment.api.EntityDesc.class;
0442:                        pobj[0] = (Object) dd;
0443:                        ptype[1] = org.objectweb.jonas_ejb.container.JEntityFactory.class;
0444:                        pobj[1] = (Object) this ;
0445:                        localhome = (JEntityLocalHome) homeclass
0446:                                .getConstructor(ptype).newInstance(pobj);
0447:                    } catch (Exception e) {
0448:                        throw new EJBException(ejbname
0449:                                + " Cannot create localhome ", e);
0450:                    }
0451:                    // register it in JNDI
0452:                    try {
0453:                        localhome.register();
0454:                    } catch (Exception e) {
0455:                        throw new EJBException(ejbname
0456:                                + " Cannot register localhome ", e);
0457:                    }
0458:                }
0459:            }
0460:
0461:            /**
0462:             * stop this EJB.
0463:             * Mainly unregister it in JNDI.
0464:             */
0465:            public void stop() {
0466:                if (TraceEjb.isDebugIc()) {
0467:                    TraceEjb.interp.log(BasicLevel.DEBUG, ejbname);
0468:                }
0469:                try {
0470:                    if (home != null) {
0471:                        home.unregister();
0472:                    }
0473:                    if (localhome != null) {
0474:                        localhome.unregister();
0475:                    }
0476:                } catch (NamingException e) {
0477:                }
0478:                stopContainer();
0479:            }
0480:
0481:            // --------------------------------------------------------------
0482:            // Instance Pool Management
0483:            // --------------------------------------------------------------
0484:
0485:            /**
0486:             * freelist of JEntityContext's
0487:             */
0488:            protected List bctxlist = new ArrayList();
0489:
0490:            /**
0491:             * @return the Instance pool size for this Ejb
0492:             */
0493:            public int getPoolSize() {
0494:                return bctxlist.size();
0495:            }
0496:
0497:            /**
0498:             * Current number of instances in memory
0499:             */
0500:            protected int instanceCount = 0;
0501:
0502:            /**
0503:             * @return current cache size
0504:             */
0505:            public int getCacheSize() {
0506:                return instanceCount;
0507:            }
0508:
0509:            /**
0510:             * @return true if max-cache-size has been reached
0511:             */
0512:            public boolean tooManyInstances() {
0513:                return (maxCacheSize > 0 && instanceCount >= maxCacheSize);
0514:            }
0515:
0516:            /**
0517:             * True if cannot overtake max-cache-size
0518:             */
0519:            protected boolean hardLimit = false;
0520:
0521:            /**
0522:             * @return true if hard limit for max-cache-size
0523:             */
0524:            public boolean isHardLimit() {
0525:                return hardLimit;
0526:            }
0527:
0528:            /**
0529:             * nb of threads waiting for an instance
0530:             */
0531:            private int currentWaiters = 0;
0532:
0533:            /**
0534:             * @return current number of instance waiters
0535:             */
0536:            public int getCurrentWaiters() {
0537:                return currentWaiters;
0538:            }
0539:
0540:            /**
0541:             * max nb of milliseconds to wait for an instance when pool is empty
0542:             */
0543:            private long waiterTimeout = 10000L;
0544:
0545:            /**
0546:             * @return waiter timeout in seconds
0547:             */
0548:            public int getMaxWaitTime() {
0549:                return (int) (waiterTimeout / 1000L);
0550:            }
0551:
0552:            /**
0553:             * @param sec max time to wait for a connection, in seconds
0554:             */
0555:            public void setMaxWaitTime(int sec) {
0556:                waiterTimeout = sec * 1000L;
0557:            }
0558:
0559:            /**
0560:             * Init the pool of instances
0561:             */
0562:            public void initInstancePool() {
0563:                // pre-allocate a set of JEntityContext (bean instances)
0564:                Context bnctx = setComponentContext(); // for createNewInstance
0565:                for (int i = 0; i < minPoolSize; i++) {
0566:                    JEntityContext ctx = null;
0567:                    try {
0568:                        ctx = createNewInstance(null);
0569:                        synchronized (bctxlist) {
0570:                            bctxlist.add(ctx);
0571:                            instanceCount++;
0572:                        }
0573:                    } catch (Exception e) {
0574:                        TraceEjb.logger.log(BasicLevel.WARN, ejbname
0575:                                + " cannot create new instance", e);
0576:                        break;
0577:                    }
0578:                }
0579:                resetComponentContext(bnctx);
0580:            }
0581:
0582:            /**
0583:             * Get a Context from the pool, or create a new one if no more
0584:             * available in the pool.
0585:             * This JContext must be initialized then by the caller.
0586:             * @return a JEntityContext, not initialized.
0587:             */
0588:            public JEntityContext getJContext(JEntitySwitch es) {
0589:                if (TraceEjb.isDebugIc()) {
0590:                    TraceEjb.interp.log(BasicLevel.DEBUG, ejbname);
0591:                }
0592:                JEntityContext bctx = null;
0593:
0594:                // Prevent a max-cache-size reached exception, if possible.
0595:                int limit = maxCacheSize - maxCacheSize / 15;
0596:                if (instanceCount >= limit && limit > minPoolSize) {
0597:                    // ask swapper to call reduceCache()
0598:                    // if maxcachesize will be reached soon, or is reached, or is highly
0599:                    // overtaken.
0600:                    if (instanceCount > maxCacheSize + limit
0601:                            || instanceCount == limit
0602:                            || instanceCount == maxCacheSize) {
0603:                        if (TraceEjb.isDebugSwapper()) {
0604:                            TraceEjb.swapper.log(BasicLevel.DEBUG, ejbname
0605:                                    + ": Too many instances :" + instanceCount
0606:                                    + ", max=" + maxCacheSize);
0607:                        }
0608:                        cont.registerBF(this );
0609:                    }
0610:                }
0611:
0612:                // try to find a free context in the pool
0613:                long timetowait = waiterTimeout;
0614:                long starttime = 0;
0615:                synchronized (bctxlist) {
0616:                    while (bctx == null) {
0617:                        if (bctxlist.isEmpty()) {
0618:                            // pool is empty
0619:                            if (!hardLimit || !tooManyInstances()) {
0620:                                // If can create more instances, go ahead.
0621:                                instanceCount++;
0622:                                break;
0623:                            }
0624:                            // If a timeout has been specified, wait
0625:                            if (timetowait > 0) {
0626:                                currentWaiters++;
0627:                                if (starttime == 0) {
0628:                                    starttime = System.currentTimeMillis();
0629:                                    if (TraceEjb.isDebugSwapper()) {
0630:                                        TraceEjb.swapper.log(BasicLevel.DEBUG,
0631:                                                "WAITING " + ejbname);
0632:                                    }
0633:                                }
0634:                                try {
0635:                                    bctxlist.wait(timetowait);
0636:                                } catch (InterruptedException e) {
0637:                                    TraceEjb.swapper.log(BasicLevel.WARN,
0638:                                            "INTERRUPTED " + ejbname);
0639:                                } finally {
0640:                                    currentWaiters--;
0641:                                }
0642:                                long stoptime = System.currentTimeMillis();
0643:                                long stillwaited = stoptime - starttime;
0644:                                timetowait = waiterTimeout - stillwaited;
0645:                            } else {
0646:                                // max-wait-time elapsed
0647:                                TraceEjb.swapper.log(BasicLevel.ERROR,
0648:                                        "max-cache-size reached on " + ejbname);
0649:                                throw new EJBException(
0650:                                        "max-cache-size reached on " + ejbname);
0651:                            }
0652:                        } else {
0653:                            // we got an instance from the pool.
0654:                            bctx = (JEntityContext) bctxlist.remove(0);
0655:                        }
0656:                    }
0657:                }
0658:
0659:                if (bctx == null) {
0660:                    // create a new one if pool empty
0661:                    try {
0662:                        bctx = createNewInstance(es);
0663:                    } catch (Exception e) {
0664:                        instanceCount--;
0665:                        throw new EJBException("Cannot create a new instance ",
0666:                                e);
0667:                    }
0668:                }
0669:
0670:                // DEBUG
0671:                if (bctx.isInitialized()) {
0672:                    TraceEjb.context.log(BasicLevel.ERROR, ejbname
0673:                            + "Context already initialized!");
0674:                }
0675:
0676:                return bctx;
0677:            }
0678:
0679:            /**
0680:             * Release a Context
0681:             * @param ctx - The JContext to release.
0682:             * @param poolaction 0=never pool, 1=pool if < MinPoolSize, 2=pool if < MaxCacheSize
0683:             */
0684:            public void releaseJContext(JContext ctx, int poolaction) {
0685:                TraceEjb.context.log(BasicLevel.DEBUG, ejbname);
0686:                JEntityContext bctx = (JEntityContext) ctx;
0687:                bctx.razEntityContext();
0688:                boolean poolit = true;
0689:                synchronized (bctxlist) {
0690:                    switch (poolaction) {
0691:                    case 0:
0692:                        poolit = false;
0693:                        break;
0694:                    case 1:
0695:                        poolit = (bctxlist.size() < minPoolSize);
0696:                        break;
0697:                    default:
0698:                        poolit = !tooManyInstances();
0699:                        break;
0700:                    }
0701:                    if (poolit) {
0702:                        bctxlist.add(bctx);
0703:                    } else {
0704:                        instanceCount--;
0705:                    }
0706:                    // Someone may be waiting for an instance.
0707:                    if (currentWaiters > 0) {
0708:                        bctxlist.notify();
0709:                    }
0710:                }
0711:            }
0712:
0713:            /**
0714:             * Release a Context [deprecated]
0715:             * @param ctx - The JContext to release.
0716:             */
0717:            public void releaseJContext(JContext ctx) {
0718:                releaseJContext(ctx, 2);
0719:            }
0720:
0721:            protected JEntityContext createNewContext(EntityBean bean) {
0722:                return new JEntityContext(this , bean);
0723:            }
0724:
0725:            /**
0726:             * Create a new instance of the bean and its EntityContext
0727:             * In case of CMP, the bean class is derived to manage entity persistence.
0728:             * @return JEntityContext
0729:             * @throws Exception cannot instantiate bean
0730:             */
0731:            protected JEntityContext createNewInstance(JEntitySwitch es)
0732:                    throws Exception {
0733:                if (TraceEjb.isDebugIc()) {
0734:                    TraceEjb.interp.log(BasicLevel.DEBUG, ejbname);
0735:                }
0736:
0737:                // create the bean instance
0738:                EntityBean bean = null;
0739:                try {
0740:                    bean = (EntityBean) beanclass.newInstance();
0741:                } catch (Exception e) {
0742:                    TraceEjb.logger.log(BasicLevel.ERROR, ejbname
0743:                            + " cannot instantiate bean " + instanceCount);
0744:                    throw e;
0745:                }
0746:
0747:                // create a new EntityContext and bind it to the instance
0748:                JEntityContext ec = createNewContext(bean);
0749:                bean.setEntityContext(ec);
0750:                ec.setState(1);
0751:
0752:                return ec;
0753:            }
0754:
0755:            /**
0756:             * Synchronize all dirty instances
0757:             * Does nothing if not CS policy.
0758:             * @param alwaysStore True if we want to store modify instances
0759:             * even if passivation timeout is not reached.
0760:             */
0761:            public void syncDirty(boolean alwaysStore) {
0762:
0763:                if (!mustSyncDirtyEntities) {
0764:                    // nothing to do
0765:                    return;
0766:                }
0767:
0768:                if (TraceEjb.isDebugSwapper()) {
0769:                    TraceEjb.swapper.log(BasicLevel.DEBUG, ejbname
0770:                            + " cacheSize = " + getCacheSize());
0771:                    TraceEjb.swapper.log(BasicLevel.DEBUG, ejbname
0772:                            + " dirtyList size = " + dirtyList.size());
0773:                }
0774:
0775:                // Set the JNDI component context (for ejbStore)
0776:                Context bnctx = setComponentContext();
0777:
0778:                // try to passivate all instances and build a new list.
0779:                LinkedList wsdone = new LinkedList();
0780:                synchronized (this ) {
0781:                    for (ListIterator i = dirtyList.listIterator(0); i
0782:                            .hasNext();) {
0783:                        JEntitySwitch es = (JEntitySwitch) i.next();
0784:                        switch (es.passivateIH(alwaysStore, false)) {
0785:                        case JEntitySwitch.ALL_DONE:
0786:                            i.remove();
0787:                            break;
0788:                        case JEntitySwitch.STORED:
0789:                            i.remove();
0790:                            wsdone.addLast(es);
0791:                            break;
0792:                        case JEntitySwitch.NOT_DONE:
0793:                            if (TraceEjb.isDebugSwapper()) {
0794:                                TraceEjb.swapper.log(BasicLevel.DEBUG, ejbname
0795:                                        + " busy");
0796:                            }
0797:                            break;
0798:                        }
0799:                    }
0800:                }
0801:
0802:                // for each instance passivated, notify it's OK to continue.
0803:                // must be done after all instances are passivated, in case of relations.
0804:                mustSyncDirtyEntities = false; // do this before endIH
0805:                for (ListIterator i = wsdone.listIterator(0); i.hasNext();) {
0806:                    JEntitySwitch es = (JEntitySwitch) i.next();
0807:                    es.endIH();
0808:                }
0809:
0810:                // Reset old value for component context
0811:                resetComponentContext(bnctx);
0812:            }
0813:
0814:            /**
0815:             * Reduce number of instances in memory
0816:             * passivate all instances that are not busy and not used very recently
0817:             */
0818:            public void reduceCache() {
0819:                TraceEjb.swapper.log(BasicLevel.DEBUG, ejbname);
0820:
0821:                // Get the list of PK.
0822:                HashMap clone = null;
0823:                synchronized (this ) {
0824:                    clone = (HashMap) pklist.clone();
0825:                }
0826:                if (clone.size() == 0) {
0827:                    return;
0828:                }
0829:
0830:                TraceEjb.swapper.log(BasicLevel.DEBUG, ejbname);
0831:
0832:                // Set classloader for getting the right component context
0833:                ClassLoader old = Thread.currentThread()
0834:                        .getContextClassLoader();
0835:                Thread.currentThread().setContextClassLoader(myClassLoader());
0836:
0837:                // Set the JNDI component context (for ejbStore)
0838:                Context bnctx = setComponentContext();
0839:
0840:                JEntitySwitch bs = null;
0841:                for (Iterator i = clone.values().iterator(); i.hasNext();) {
0842:                    bs = (JEntitySwitch) i.next();
0843:                    bs.passivateIH(true, true);
0844:                }
0845:                // Reset old value for component context
0846:                resetComponentContext(bnctx);
0847:                Thread.currentThread().setContextClassLoader(old);
0848:            }
0849:
0850:            // --------------------------------------------------------------
0851:            // PK list - JEntitySwitch cache Management
0852:            // --------------------------------------------------------------
0853:
0854:            /**
0855:             * List of JEntitySwitch objects
0856:             * At each PK is associated a JEntitySwitch object
0857:             */
0858:            private HashMap pklist = new HashMap();
0859:
0860:            /**
0861:             * dirty list of JEntitySwitch
0862:             * Only used for CS policy (non transacted modifying methods)
0863:             */
0864:            private LinkedList dirtyList = new LinkedList();
0865:
0866:            private boolean mustSyncDirtyEntities = false;
0867:
0868:            /**
0869:             * @return true if dirty list is not empty
0870:             * Only used for CS policy (non transacted modifying methods)
0871:             */
0872:            public boolean dirtyInstances() {
0873:                return mustSyncDirtyEntities;
0874:            }
0875:
0876:            /**
0877:             * This field is used to generate an uid for unique automatic pk
0878:             */
0879:            private static final long DIZINIT = 1132241379300L;
0880:            private int ucount = (int) (System.currentTimeMillis() - DIZINIT) / 100;
0881:
0882:            /**
0883:             * Calculate a new uid for automatic pk creation Used by JEntityCmpJdbc.vm
0884:             * @return int (unique pk)
0885:             */
0886:            public int calculateAutomaticPk() {
0887:                if (TraceEjb.isDebugIc()) {
0888:                    TraceEjb.interp.log(BasicLevel.DEBUG, ejbname);
0889:                }
0890:                int uid;
0891:                synchronized (this ) {
0892:                    uid = ucount++;
0893:                }
0894:                return uid;
0895:            }
0896:
0897:            /**
0898:             * Encode PK. This does nothing, except in case of CMP2
0899:             * @return String representation of the PK
0900:             */
0901:            public Serializable encodePK(Serializable pk) {
0902:                return pk;
0903:            }
0904:
0905:            /**
0906:             * Decode PK. This does nothing, except in case of CMP2
0907:             * @return PK matching the String
0908:             */
0909:            public Serializable decodePK(Serializable strpk) {
0910:                return strpk;
0911:            }
0912:
0913:            /**
0914:             * get EJB by its PK
0915:             * Creates if not exist yet.
0916:             * @param pk The Primary Key Object
0917:             * @return The JEntitySwitch matching the PK.
0918:             */
0919:            public synchronized JEntitySwitch getEJB(Object pk) {
0920:
0921:                if (TraceEjb.isDebugIc()) {
0922:                    TraceEjb.interp.log(BasicLevel.DEBUG, ejbname);
0923:                }
0924:
0925:                if (pk == null) {
0926:                    TraceEjb.logger.log(BasicLevel.ERROR, "pk null ???");
0927:                    return null;
0928:                }
0929:                JEntitySwitch bs = (JEntitySwitch) pklist.get(pk);
0930:                if (bs == null) {
0931:                    bs = getJEntitySwitch();
0932:                    bs.init(this , pk);
0933:                    pklist.put(pk, bs);
0934:                }
0935:                return bs;
0936:            }
0937:
0938:            /**
0939:             * get EJB by its PK. If not exist yet, map the EntitySwitch to the PK.
0940:             * @param pk The Primary Key Object
0941:             * @param bs the Entityswitch
0942:             * @return The JEntitySwitch matching the PK, or null if none exist.
0943:             */
0944:            public synchronized JEntitySwitch existEJB(Object pk,
0945:                    JEntitySwitch bs) {
0946:                if (pk == null) {
0947:                    TraceEjb.logger.log(BasicLevel.ERROR, "pk null ???");
0948:                    return null;
0949:                }
0950:                JEntitySwitch ret = (JEntitySwitch) pklist.get(pk);
0951:                if (ret == null && bs != null) {
0952:                    // Bind new EntitySwitch while we got the lock.
0953:                    bs.init(this , pk);
0954:                    pklist.put(pk, bs);
0955:                }
0956:                return ret;
0957:            }
0958:
0959:            /**
0960:             * rebind a PK with a JEntitySwitch (called by create methods)
0961:             * @param tx current Transaction
0962:             * @param bctx The EntityContext
0963:             * @param pk The Primary Key Object
0964:             * @return true if bs has been added to the PK list.
0965:             */
0966:            public boolean rebindEJB(Transaction tx, JEntityContext bctx,
0967:                    Object pk) {
0968:                if (TraceEjb.isDebugIc()) {
0969:                    TraceEjb.interp.log(BasicLevel.DEBUG, ejbname);
0970:                }
0971:
0972:                if (pk == null) {
0973:                    TraceEjb.logger.log(BasicLevel.ERROR, "pk null ???");
0974:                    return false;
0975:                }
0976:                JEntitySwitch bs = bctx.getEntitySwitch();
0977:                JEntitySwitch old = null;
0978:                synchronized (this ) {
0979:                    old = (JEntitySwitch) pklist.get(pk);
0980:                }
0981:                boolean ret = true;
0982:                if (old != null) {
0983:                    // different cases:
0984:                    // - a create after a remove, in the same tx (or no tx)
0985:                    // - in CMP2: a "DuplicateKey".
0986:                    // - Bean removed by another server (bean shared)
0987:
0988:                    // Release completely the old EntitySwitch before binding the new one.
0989:                    // must be done outside the lock, to avoid a deadlock.
0990:                    ret = old.terminate(tx);
0991:                }
0992:                synchronized (this ) {
0993:                    bs.init(this , pk);
0994:                    pklist.put(pk, bs);
0995:                }
0996:                return ret;
0997:            }
0998:
0999:            /**
1000:             * Bind a PK with a JEntitySwitch
1001:             * @param pk The Primary Key Object
1002:             * @param bs The JEntitySwitch
1003:             */
1004:            public synchronized void bindEJB(Object pk, JEntitySwitch bs) {
1005:                if (pk == null) {
1006:                    TraceEjb.logger.log(BasicLevel.ERROR, "pk null ???");
1007:                    return;
1008:                }
1009:                if (TraceEjb.isDebugSwapper()) {
1010:                    TraceEjb.swapper.log(BasicLevel.DEBUG, ejbname);
1011:                }
1012:                bs.init(this , pk);
1013:                pklist.put(pk, bs);
1014:            }
1015:
1016:            /**
1017:             * This method allocates a new JEntitySwitch. But no association has been
1018:             * done between the primary key and the new JEntitySwitch. Therefore the
1019:             * initialisation is not done.
1020:             * @return The JEntitySwitch.
1021:             */
1022:            public JEntitySwitch getJEntitySwitch() {
1023:                switch (lockPolicy) {
1024:                case EntityDesc.LOCK_CONTAINER_READ_UNCOMMITTED:
1025:                    return new JEntitySwitchCRU();
1026:                case EntityDesc.LOCK_CONTAINER_READ_COMMITTED:
1027:                    return new JEntitySwitchCRC();
1028:                case EntityDesc.LOCK_DATABASE:
1029:                    return new JEntitySwitchDB();
1030:                case EntityDesc.LOCK_READ_ONLY:
1031:                    return new JEntitySwitchRO();
1032:                case EntityDesc.LOCK_CONTAINER_READ_WRITE:
1033:                    return new JEntitySwitchCRW();
1034:                case EntityDesc.LOCK_CONTAINER_SERIALIZED_TRANSACTED:
1035:                    return new JEntitySwitchCST();
1036:                case EntityDesc.LOCK_CONTAINER_SERIALIZED:
1037:                    return new JEntitySwitchCS();
1038:                default:
1039:                    TraceEjb.logger.log(BasicLevel.WARN,
1040:                            "lockPolicy not initilized");
1041:                    return new JEntitySwitchCS();
1042:                }
1043:            }
1044:
1045:            /**
1046:             * remove an EJB by its PK
1047:             * @param pk The Primary Key Object
1048:             */
1049:            public synchronized void removeEJB(Object pk) {
1050:                if (TraceEjb.isDebugSwapper()) {
1051:                    TraceEjb.swapper.log(BasicLevel.DEBUG, ejbname);
1052:                }
1053:                if (pk == null) {
1054:                    TraceEjb.logger.log(BasicLevel.ERROR, "pk null ???");
1055:                    return;
1056:                }
1057:                pklist.remove(pk);
1058:            }
1059:
1060:            /**
1061:             * Register an EntitySwitch in the dirty list.
1062:             * should be called each time a new instance is modified outside transaction
1063:             * @param ejb The Entity Switch to be registered
1064:             */
1065:            public synchronized void registerEJB(JEntitySwitch ejb) {
1066:                if (TraceEjb.isDebugSwapper()) {
1067:                    TraceEjb.swapper.log(BasicLevel.DEBUG, ejbname);
1068:                }
1069:                if (dirtyList.contains(ejb)) {
1070:                    TraceEjb.swapper.log(BasicLevel.ERROR, ejbname
1071:                            + " Elt already in the dirty list");
1072:                    return;
1073:                }
1074:                dirtyList.addLast(ejb);
1075:                mustSyncDirtyEntities = true;
1076:            }
1077:
1078:            /**
1079:             * Ask swapper to synchronize all dirty EntitySwitch
1080:             * Only used for container-serialized policy
1081:             */
1082:            public void synchronizeEntities() {
1083:                if (TraceEjb.isDebugSwapper()) {
1084:                    TraceEjb.swapper.log(BasicLevel.DEBUG, ejbname);
1085:                }
1086:                cont.registerBFS(this );
1087:            }
1088:
1089:            /**
1090:             * Search if this transaction is blocked in a deadlock
1091:             * @param suspect Transaction suspected to block everybody
1092:             * @return True if a deadlock has been detected.
1093:             */
1094:            public boolean isDeadLocked(Transaction suspect) {
1095:                // Get a clone of the complete list of PKs
1096:                HashMap clone = null;
1097:                synchronized (this ) {
1098:                    clone = (HashMap) pklist.clone();
1099:                }
1100:                JEntitySwitch es = null;
1101:                // Build a list of all transactions that block "suspect" tx.
1102:                ArrayList blktx = new ArrayList();
1103:                Transaction testedtx = suspect;
1104:                // Loop until a result is found (true or false)
1105:                while (true) {
1106:                    for (Iterator i = clone.values().iterator(); i.hasNext();) {
1107:                        es = (JEntitySwitch) i.next();
1108:                        Transaction tx = es.getBlockingTx(testedtx);
1109:                        if (tx != null) {
1110:                            if (tx.equals(suspect)) {
1111:                                TraceEjb.synchro.log(BasicLevel.WARN,
1112:                                        "Found a deadlock on :" + tx);
1113:                                // found a deadlock
1114:                                return true;
1115:                            }
1116:                            blktx.add(tx);
1117:                        }
1118:                    }
1119:                    if (blktx.size() == 0) {
1120:                        // no deadlock found.
1121:                        TraceEjb.synchro.log(BasicLevel.DEBUG,
1122:                                "No deadlock found");
1123:                        return false;
1124:                    }
1125:                    testedtx = (Transaction) blktx.remove(0);
1126:                }
1127:            }
1128:
1129:            /**
1130:             * Take a dump of current entity counters and return them
1131:             * @return EntityCounters
1132:             */
1133:            public synchronized EntityCounters getEntityCounters() {
1134:                EntityCounters ec = new EntityCounters();
1135:                Collection coll = pklist.values();
1136:                ec.pk = pklist.size();
1137:                for (Iterator i = coll.iterator(); i.hasNext();) {
1138:                    JEntitySwitch es = (JEntitySwitch) i.next();
1139:                    switch (es.getState()) {
1140:                    case 0:
1141:                        ec.inTx++;
1142:                        break;
1143:                    case 1:
1144:                        ec.outTx++;
1145:                        break;
1146:                    case 2:
1147:                        ec.idle++;
1148:                        break;
1149:                    case 3:
1150:                        ec.passive++;
1151:                        break;
1152:                    case 4:
1153:                        ec.removed++;
1154:                        break;
1155:                    }
1156:                }
1157:                return ec;
1158:            }
1159:
1160:            // --------------------------------------------------------------
1161:            // transaction association management
1162:            // --------------------------------------------------------------
1163:
1164:            /**
1165:             * List of Transaction Listeners.
1166:             * At each Transaction is associated a TxListener object
1167:             */
1168:            protected HashMap txlist = new HashMap();
1169:
1170:            /**
1171:             * synchronize data modified in this transaction.
1172:             * this is necessary in case of finder method, because
1173:             * ejb-ql looks for on disk.
1174:             * @param tx the Transaction
1175:             */
1176:            public void syncForFind(Transaction tx) {
1177:                if (TraceEjb.isDebugIc()) {
1178:                    TraceEjb.interp.log(BasicLevel.DEBUG, ejbname);
1179:                }
1180:                if (tx == null) {
1181:                    if (lockPolicy == EntityDesc.LOCK_CONTAINER_SERIALIZED) {
1182:                        syncDirty(true);
1183:                    }
1184:                } else {
1185:                    this .getContainer().storeAll(tx);
1186:                }
1187:            }
1188:
1189:            /**
1190:             * synchronize data modified in the current transaction.
1191:             * this is necessary in case of select method, because
1192:             * ejb-ql looks for on disk.
1193:             */
1194:            public void syncForSelect() {
1195:                if (TraceEjb.isDebugIc()) {
1196:                    TraceEjb.interp.log(BasicLevel.DEBUG, ejbname);
1197:                }
1198:                // First of all, get the current transaction
1199:                Transaction currtx = null;
1200:                try {
1201:                    currtx = tm.getTransaction();
1202:                    if (TraceEjb.isDebugTx()) {
1203:                        TraceEjb.tx.log(BasicLevel.DEBUG, "currtx=" + currtx);
1204:                    }
1205:                } catch (SystemException e) {
1206:                    TraceEjb.logger.log(BasicLevel.ERROR,
1207:                            "system exception while getting transaction:", e);
1208:                    return;
1209:                }
1210:                // Sync dirty instances for the current transaction
1211:                syncForFind(currtx);
1212:            }
1213:
1214:            /**
1215:             * For storing entities modified in tx
1216:             * @param tx current transaction
1217:             * @see org.objectweb.jonas_ejb.container.BeanFactory#storeInstances(javax.transaction.Transaction)
1218:             */
1219:            public void storeInstances(Transaction tx) {
1220:                TxListener txl = (TxListener) txlist.get(tx);
1221:                if (txl != null) {
1222:                    txl.storeInstances();
1223:                }
1224:
1225:            }
1226:
1227:            /**
1228:             * Remove a Transaction Listener from the list.
1229:             * @param tx the Transaction to remove
1230:             */
1231:            public void removeTxListener(Transaction tx) {
1232:                if (TraceEjb.isDebugIc()) {
1233:                    TraceEjb.interp.log(BasicLevel.DEBUG, ejbname);
1234:                }
1235:                txlist.remove(tx);
1236:            }
1237:
1238:            /**
1239:             * Unregister a Context/Instance in the transaction.
1240:             * @param tx current Transaction
1241:             * @param ctx JEntityContext to be registered
1242:             */
1243:            public void unregisterContext(Transaction tx, JEntityContext ec)
1244:                    throws IllegalStateException {
1245:                if (TraceEjb.isDebugIc()) {
1246:                    TraceEjb.interp.log(BasicLevel.DEBUG, ejbname);
1247:                }
1248:                // Get the TXListener associated to this tx.
1249:                TxListener txl = (TxListener) txlist.get(tx);
1250:                if (txl == null) {
1251:                    return;
1252:                }
1253:                txl.removeInstance(ec);
1254:            }
1255:
1256:            /**
1257:             * Register a Context/Instance in the transaction.
1258:             * @param tx current Transaction
1259:             * @param ctx JEntityContext to be registered
1260:             * @return true if instance has been registered.
1261:             */
1262:            public boolean registerContext(Transaction tx, JEntityContext ec)
1263:                    throws IllegalStateException {
1264:                if (TraceEjb.isDebugIc()) {
1265:                    TraceEjb.interp.log(BasicLevel.DEBUG, ejbname);
1266:                }
1267:
1268:                // Get the TXListener associated to this tx, or create it.
1269:                TxListener txl = (TxListener) txlist.get(tx);
1270:                if (txl == null) {
1271:                    txl = new TxListener(this , tx);
1272:                    // register it as Synchronization.
1273:                    try {
1274:                        tx.registerSynchronization(txl);
1275:                    } catch (RollbackException e) {
1276:                        if (TraceEjb.isVerbose()) {
1277:                            TraceEjb.logger
1278:                                    .log(
1279:                                            BasicLevel.WARN,
1280:                                            ejbname
1281:                                                    + " transaction has been marked rollbackOnly",
1282:                                            e);
1283:                        }
1284:                    } catch (SystemException e) {
1285:                        TraceEjb.logger.log(BasicLevel.ERROR, ejbname
1286:                                + " cannot register synchro ", e);
1287:                        // forget txl.
1288:                        throw new IllegalStateException(
1289:                                "cannot register synchro");
1290:                    }
1291:                    txlist.put(tx, txl);
1292:                }
1293:
1294:                // Add the JEntityContext
1295:                txl.addInstance(ec);
1296:                return true;
1297:            }
1298:
1299:            /**
1300:             * Check Transaction before calling a method on a bean. For Entity beans,
1301:             * the only possible case is "Container Managed Tx"
1302:             * @param rctx The Request Context
1303:             */
1304:            public void checkTransaction(RequestCtx rctx) {
1305:                checkTransactionContainer(rctx);
1306:            }
1307:
1308:            // -----------------------------------------------------------------------
1309:            // Timer Service Implementation
1310:            // ----------------------------------------------------------------------
1311:
1312:            /**
1313:             * Obtains the TimerService associated for this Bean
1314:             * @return a JTimerService instance.
1315:             */
1316:            public TimerService getTimerService() {
1317:                return this ;
1318:            }
1319:
1320:            /**
1321:             * Illegal operation: timers are associated with a PK
1322:             * @see javax.ejb.TimerService#createTimer(long, java.io.Serializable)
1323:             */
1324:            public Timer createTimer(long arg0, Serializable arg1)
1325:                    throws IllegalArgumentException, IllegalStateException,
1326:                    EJBException {
1327:                throw new IllegalStateException(
1328:                        "timers are associated with a PK");
1329:            }
1330:
1331:            /**
1332:             * Illegal operation: timers are associated with a PK
1333:            /* (non-Javadoc)
1334:             * @see javax.ejb.TimerService#createTimer(long, long, java.io.Serializable)
1335:             */
1336:            public Timer createTimer(long arg0, long arg1, Serializable arg2)
1337:                    throws IllegalArgumentException, IllegalStateException,
1338:                    EJBException {
1339:                throw new IllegalStateException(
1340:                        "timers are associated with a PK");
1341:            }
1342:
1343:            /**
1344:             * Illegal operation: timers are associated with a PK
1345:             * @see javax.ejb.TimerService#createTimer(java.util.Date, java.io.Serializable)
1346:             */
1347:            public Timer createTimer(Date arg0, Serializable arg1)
1348:                    throws IllegalArgumentException, IllegalStateException,
1349:                    EJBException {
1350:                throw new IllegalStateException(
1351:                        "timers are associated with a PK");
1352:            }
1353:
1354:            /**
1355:             * Illegal operation: timers are associated with a PK
1356:             * @see javax.ejb.TimerService#createTimer(java.util.Date, long, java.io.Serializable)
1357:             */
1358:            public Timer createTimer(Date arg0, long arg1, Serializable arg2)
1359:                    throws IllegalArgumentException, IllegalStateException,
1360:                    EJBException {
1361:                throw new IllegalStateException(
1362:                        "timers are associated with a PK");
1363:            }
1364:
1365:            /**
1366:             * Illegal operation: timers are associated with a PK
1367:             * @see javax.ejb.TimerService#getTimers()
1368:             */
1369:            public Collection getTimers() throws IllegalStateException,
1370:                    EJBException {
1371:                throw new IllegalStateException(
1372:                        "timers are associated with a PK");
1373:            }
1374:
1375:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.