JEntityFactory.java

00001 
00026 package org.objectweb.jonas_ejb.container;
00027 
00028 import java.io.Serializable;
00029 import java.util.ArrayList;
00030 import java.util.Collection;
00031 import java.util.Collections;
00032 import java.util.Date;
00033 import java.util.HashMap;
00034 import java.util.Iterator;
00035 import java.util.LinkedList;
00036 import java.util.List;
00037 import java.util.ListIterator;
00038 
00039 import javax.ejb.EJBException;
00040 import javax.ejb.EntityBean;
00041 import javax.ejb.FinderException;
00042 import javax.ejb.Timer;
00043 import javax.ejb.TimerService;
00044 import javax.naming.Context;
00045 import javax.naming.NamingException;
00046 import javax.transaction.RollbackException;
00047 import javax.transaction.SystemException;
00048 import javax.transaction.Transaction;
00049 
00050 import org.objectweb.jonas_ejb.deployment.api.EntityDesc;
00051 import org.objectweb.jonas_ejb.deployment.api.EntityJdbcCmp1Desc;
00052 import org.objectweb.jonas_ejb.deployment.api.EntityJdbcCmp2Desc;
00053 import org.objectweb.jorm.naming.api.PExceptionNaming;
00054 import org.objectweb.jorm.naming.api.PName;
00055 
00056 import org.objectweb.util.monolog.api.BasicLevel;
00057 
00066 public class JEntityFactory extends JFactory implements TimerService {
00067 
00071     protected JEntityHome home = null;
00072 
00076     protected JEntityLocalHome localhome = null;
00077 
00081     protected boolean reentrant;
00082 
00088     protected boolean shared = false;
00089 
00093     protected int lockPolicy;
00094 
00098     protected boolean prefetch = false;
00099 
00103     protected List bctxlist = new ArrayList();
00104 
00108     protected int minPoolSize;
00109 
00110     protected int instanceCount = 0;
00111 
00112     protected int maxCacheSize;
00113 
00114     protected int inactivityTimeout; // sec.
00115 
00120     protected HashMap pklist = new HashMap();
00121 
00126     protected HashMap txlist = new HashMap();
00127 
00131     private LinkedList dirtyList = new LinkedList();
00132 
00133     private boolean mustSyncDirtyEntities = false;
00134 
00135     // Datasource in case of CMP
00136     protected Object datasource = null;
00137 
00141     private static int ucount = 1;
00142 
00146     String dsname = null;
00147 
00151     public JEntityFactory() {
00152         TraceEjb.interp.log(BasicLevel.DEBUG, "");
00153     }
00154 
00160     public void init(EntityDesc dd, JContainer cont) {
00161         super.init(dd, cont);
00162         reentrant = dd.isReentrant();
00163         shared = dd.isShared();
00164         lockPolicy = dd.getLockPolicy();
00165         prefetch = dd.isPrefetch();
00166         if (lockPolicy == EntityDesc.LOCK_CONTAINER_READ_UNCOMMITTED && prefetch) {
00167             throw new EJBException("Cannot set READ_UNCOMMITTED and prefetch for a bean");
00168         }
00169         inactivityTimeout = dd.getInactivityTimeout();
00170         maxCacheSize = dd.getCacheMax();
00171         minPoolSize = dd.getPoolMin();
00172 
00173         // Finds the DataSource associated to the bean
00174         // Useful for Entity with Container Managed Persistence.
00175         if (dd instanceof EntityJdbcCmp1Desc) {
00176             dsname = ((EntityJdbcCmp1Desc) dd).getDatasourceJndiName();
00177             if (dsname != null) {
00178                 try {
00179                     datasource = getInitialContext().lookup(dsname);
00180                 } catch (NamingException e) {
00181                     TraceEjb.logger.log(BasicLevel.ERROR, dsname + " is not known by the EJB server.", e);
00182                     throw new EJBException(dsname + " unknown");
00183                 }
00184             }
00185         }
00186 
00187         if (dd instanceof EntityJdbcCmp2Desc) {
00188             dsname = ((EntityJdbcCmp2Desc) dd).getDatasourceJndiName();
00189             if (dsname != null) {
00190                 try {
00191                     datasource = getInitialContext().lookup(dsname);
00192                 } catch (NamingException e) {
00193                     TraceEjb.logger.log(BasicLevel.ERROR, dsname + " is not known by the EJB server.");
00194                     throw new EJBException(dsname + " unknown");
00195                 }
00196             }
00197         }
00198 
00199         // Create the Home if defined in DD
00200         Class homeclass = null;
00201         String clname = dd.getFullWrpHomeName();
00202         if (clname != null) {
00203             try {
00204                 homeclass = cont.getClassLoader().loadClass(clname);
00205             } catch (ClassNotFoundException e) {
00206                 throw new EJBException(ejbname + "Cannot load " + clname);
00207             }
00208             if (TraceEjb.isDebugIc()) {
00209                 TraceEjb.interp.log(BasicLevel.DEBUG, ejbname + ": " + clname + " loaded");
00210             }
00211             try {
00212                 // new JEntityHome(dd, this)
00213                 int nbp = 2;
00214                 Class[] ptype = new Class[nbp];
00215                 Object[] pobj = new Object[nbp];
00216                 ptype[0] = org.objectweb.jonas_ejb.deployment.api.EntityDesc.class;
00217                 pobj[0] = (Object) dd;
00218                 ptype[1] = org.objectweb.jonas_ejb.container.JEntityFactory.class;
00219                 pobj[1] = (Object) this;
00220                 home = (JEntityHome) homeclass.getConstructor(ptype).newInstance(pobj);
00221             } catch (Exception e) {
00222                 if (TraceEjb.isVerbose()) {
00223                     e.printStackTrace();
00224                 }
00225                 throw new EJBException(ejbname + " Cannot create home ", e);
00226             }
00227 
00228             // register it in JNDI
00229             try {
00230                 home.register();
00231             } catch (Exception e) {
00232                 throw new EJBException(ejbname + " Cannot register home ", e);
00233             }
00234         }
00235 
00236         // Create the LocalHome if defined in DD
00237         clname = dd.getFullWrpLocalHomeName();
00238         if (clname != null) {
00239             try {
00240                 homeclass = cont.getClassLoader().loadClass(clname);
00241             } catch (ClassNotFoundException e) {
00242                 TraceEjb.logger.log(BasicLevel.ERROR, ejbname + " cannot load " + clname);
00243                 throw new EJBException("Cannot load " + clname);
00244             }
00245             if (TraceEjb.isDebugIc()) {
00246                 TraceEjb.interp.log(BasicLevel.DEBUG, ejbname + ": " + clname + " loaded");
00247             }
00248             try {
00249                 // new JEntityLocalHome(dd, this)
00250                 int nbp = 2;
00251                 Class[] ptype = new Class[nbp];
00252                 Object[] pobj = new Object[nbp];
00253                 ptype[0] = org.objectweb.jonas_ejb.deployment.api.EntityDesc.class;
00254                 pobj[0] = (Object) dd;
00255                 ptype[1] = org.objectweb.jonas_ejb.container.JEntityFactory.class;
00256                 pobj[1] = (Object) this;
00257                 localhome = (JEntityLocalHome) homeclass.getConstructor(ptype).newInstance(pobj);
00258             } catch (Exception e) {
00259                 throw new EJBException(ejbname + " Cannot create localhome ", e);
00260             }
00261             // register it in JNDI
00262             try {
00263                 localhome.register();
00264             } catch (Exception e) {
00265                 throw new EJBException(ejbname + " Cannot register localhome ", e);
00266             }
00267         }
00268     }
00269     
00273     public void initInstancePool() {
00274         // pre-allocate a set of JEntityContext (bean instances)
00275         Context bnctx = setComponentContext(); // for createNewInstance
00276         for (int i = 0; i < minPoolSize; i++) {
00277             JEntityContext ctx = null;
00278             try {
00279                 ctx = createNewInstance(null);
00280                 synchronized(bctxlist) {
00281                     bctxlist.add(ctx);
00282                 }
00283             } catch (Exception e) {
00284                 TraceEjb.logger.log(BasicLevel.ERROR, ejbname + " cannot create new instance", e);
00285                 throw new EJBException(ejbname + " Cannot init pool of instances ", e);
00286             }
00287         }
00288         resetComponentContext(bnctx);
00289     }
00290 
00297     public synchronized JEntitySwitch getEJB(Object pk) {
00298 
00299         TraceEjb.interp.log(BasicLevel.DEBUG, ejbname);
00300 
00301         if (pk == null) {
00302             TraceEjb.logger.log(BasicLevel.ERROR, "pk null ???");
00303             return null;
00304         }
00305         JEntitySwitch bs = (JEntitySwitch) pklist.get(pk);
00306         if (bs == null) {
00307             bs = getJEntitySwitch();
00308             bs.init(this, pk);
00309             TraceEjb.interp.log(BasicLevel.DEBUG, "Adding PK to pklist:" + pk);
00310             pklist.put(pk, bs);
00311         }
00312         return bs;
00313     }
00314 
00320     public synchronized JEntitySwitch existEJB(Object pk) {
00321         if (pk == null) {
00322             TraceEjb.logger.log(BasicLevel.ERROR, "pk null ???");
00323             return null;
00324         }
00325         TraceEjb.interp.log(BasicLevel.DEBUG, "Looking for PK in pklist:" + pk);
00326         JEntitySwitch ret = (JEntitySwitch) pklist.get(pk);
00327         TraceEjb.interp.log(BasicLevel.DEBUG, ret == null ? "no" : "yes");
00328         return ret;
00329     }
00330 
00338     public boolean rebindEJB(Transaction tx, JEntityContext bctx, Object pk) {
00339         TraceEjb.interp.log(BasicLevel.DEBUG, ejbname);
00340 
00341         if (pk == null) {
00342             TraceEjb.logger.log(BasicLevel.ERROR, "pk null ???");
00343             return false;
00344         }
00345         JEntitySwitch bs = bctx.getEntitySwitch();
00346         JEntitySwitch old = null;
00347         synchronized (this) {
00348             old = (JEntitySwitch) pklist.get(pk);
00349         }
00350         boolean ret = true;
00351         if (old != null) {
00352             // different cases: 
00353             // - a create after a remove, in the same tx (or no tx)
00354             // - in CMP2: a "DuplicateKey".
00355             // - Bean removed by another server (bean shared)
00356 
00357             // Release completely the old EntitySwitch before binding the new one.
00358             // must be done outside the lock, to avoid a deadlock.
00359             ret = old.terminate(tx);
00360         }
00361         synchronized (this) {
00362             bs.init(this, pk);
00363             TraceEjb.interp.log(BasicLevel.DEBUG, "Adding PK to pklist:" + pk);
00364             pklist.put(pk, bs);
00365         }
00366         return ret;
00367     }
00368 
00374     public synchronized void bindEJB(Object pk, JEntitySwitch bs) {
00375         TraceEjb.interp.log(BasicLevel.DEBUG, ejbname);
00376         if (pk == null) {
00377             TraceEjb.logger.log(BasicLevel.ERROR, "pk null ???");
00378             return;
00379         }
00380         bs.init(this, pk);
00381         pklist.put(pk, bs);
00382     }
00383 
00390     public JEntitySwitch getJEntitySwitch() {
00391         switch (lockPolicy) {
00392             case EntityDesc.LOCK_CONTAINER_READ_UNCOMMITTED:
00393                 return new JEntitySwitchCRU();
00394             case EntityDesc.LOCK_CONTAINER_READ_COMMITTED:
00395                 return new JEntitySwitchCRC();
00396             case EntityDesc.LOCK_DATABASE:
00397                 return new JEntitySwitchDB();
00398             case EntityDesc.LOCK_READ_ONLY:
00399                 return new JEntitySwitchRO();
00400             default:
00401                 return new JEntitySwitchCS();
00402         }
00403     }
00404 
00409     public synchronized void removeEJB(Object pk) {
00410         TraceEjb.interp.log(BasicLevel.DEBUG, ejbname);
00411         if (pk == null) {
00412             TraceEjb.logger.log(BasicLevel.ERROR, "pk null ???");
00413             return;
00414         }
00415         pklist.remove(pk);
00416     }
00417 
00423     public synchronized void registerEJB(JEntitySwitch ejb) {
00424         TraceEjb.swapper.log(BasicLevel.DEBUG, ejbname);
00425         if (dirtyList.contains(ejb)) {
00426             TraceEjb.swapper.log(BasicLevel.ERROR, ejbname + " Elt already in the dirty list");
00427             return;
00428         }
00429         dirtyList.addLast(ejb);
00430         mustSyncDirtyEntities = true;
00431     }
00432 
00436     public void synchronizeEntities() {
00437         TraceEjb.swapper.log(BasicLevel.DEBUG, ejbname);
00438         cont.registerBFS(this);
00439     }
00440 
00444     public boolean dirtyInstances() {
00445         return mustSyncDirtyEntities;
00446     }
00447 
00451     public int getInactivityTimeout() {
00452         return inactivityTimeout;
00453     }
00454 
00455     // ---------------------------------------------------------------
00456     // BeanFactory implementation
00457     // ---------------------------------------------------------------
00458 
00462     public int getPoolSize() {
00463         return bctxlist.size();
00464     }
00465 
00470     public void stop() {
00471         TraceEjb.interp.log(BasicLevel.DEBUG, ejbname);
00472         try {
00473             if (home != null) {
00474                 home.unregister();
00475             }
00476             if (localhome != null) {
00477                 localhome.unregister();
00478             }
00479         } catch (NamingException e) {
00480         }
00481     }
00482 
00486     public void sync() {
00487 
00488         if (!mustSyncDirtyEntities) {
00489             TraceEjb.swapper.log(BasicLevel.DEBUG, ejbname + " cacheSize = " + getCacheSize());
00490             // nothing to do
00491             return;
00492         }
00493 
00494         TraceEjb.swapper.log(BasicLevel.DEBUG, ejbname + " dirtyList size = " + dirtyList.size());
00495 
00496         // Set the JNDI component context (for ejbStore)
00497         Context bnctx = setComponentContext();
00498 
00499         // try to passivate all instances and build a new list.
00500         LinkedList wsdone = new LinkedList();
00501         synchronized (this) {
00502             for (ListIterator i = dirtyList.listIterator(0); i.hasNext();) {
00503                 JEntitySwitch es = (JEntitySwitch) i.next();
00504                 if (es.passivateIH(false)) {
00505                     // passivation OK.
00506                     i.remove();
00507                     wsdone.addLast(es);
00508                 } else {
00509                     TraceEjb.swapper.log(BasicLevel.DEBUG, ejbname + " swapper could not passivate an instance");
00510                 }
00511             }
00512         }
00513 
00514         // for each instance passivated, notify it's OK to continue.
00515         // must be done after all instances are passivated, in case of relations.
00516         mustSyncDirtyEntities = false; // do this before endIH
00517         for (ListIterator i = wsdone.listIterator(0); i.hasNext();) {
00518             JEntitySwitch es = (JEntitySwitch) i.next();
00519             es.endIH();
00520         }
00521 
00522         // Reset old value for component context
00523         resetComponentContext(bnctx);
00524     }
00525 
00529     public void reduceCache() {
00530         TraceEjb.swapper.log(BasicLevel.DEBUG, ejbname + pklist.size());
00531         //printAllPks();
00532 
00533         // passivate all instances that are not busy
00534         // count is the number of busy instances (not freed)
00535         // other instances should be added to the pool (bctxlist)
00536         int count = 0;
00537 
00538         // Set classloader for getting the right component context
00539         ClassLoader old = Thread.currentThread().getContextClassLoader();
00540         Thread.currentThread().setContextClassLoader(myClassLoader());
00541 
00542         // Set the JNDI component context (for ejbStore)
00543         Context bnctx = setComponentContext();
00544 
00545         Collection coll = null;
00546         HashMap clone = null;
00547         synchronized (this) {
00548             clone = (HashMap) pklist.clone();
00549         }
00550         JEntitySwitch bs = null;
00551         for (Iterator i = clone.values().iterator(); i.hasNext();) {
00552             bs = (JEntitySwitch) i.next();
00553             if (!bs.passivateIH(true)) {
00554                 count++;
00555             }
00556         }
00557         // Reset old value for component context
00558         resetComponentContext(bnctx);
00559         Thread.currentThread().setContextClassLoader(old);
00560 
00561         // compute the new size we want for the pool
00562         // (if more busy instances than min size, we want an empty pool)
00563         int poolsz = minPoolSize - count;
00564         if (poolsz < 0) {
00565             poolsz = 0;
00566         }
00567 
00568         // reduce the pool to this new value
00569         synchronized (bctxlist) {
00570             TraceEjb.swapper.log(BasicLevel.DEBUG, ejbname + ": try to reduce " + bctxlist.size() + " to " + poolsz);
00571             while (bctxlist.size() > poolsz) {
00572                 ListIterator i = bctxlist.listIterator();
00573                 if (i.hasNext()) {
00574                     i.next();
00575                     i.remove();
00576                     instanceCount--;
00577                 }
00578             }
00579         }
00580         TraceEjb.swapper.log(BasicLevel.DEBUG, ejbname + " cacheSize= " + getCacheSize());
00581         printMemoryUsage();
00582     }
00583 
00587     public JHome getHome() {
00588         return home;
00589     }
00590 
00594     public JLocalHome getLocalHome() {
00595         return localhome;
00596     }
00597 
00598     // ---------------------------------------------------------------
00599     // Context Pool
00600     // ---------------------------------------------------------------
00601 
00608     public JEntityContext getJContext(JEntitySwitch es) {
00609         TraceEjb.interp.log(BasicLevel.DEBUG, ejbname);
00610         JEntityContext bctx = null;
00611 
00612         // try to find a free context in the pool
00613         synchronized (bctxlist) {
00614             try {
00615                 ListIterator i = bctxlist.listIterator();
00616                 if (i.hasNext()) {
00617                     bctx = (JEntityContext) i.next();
00618                     i.remove();
00619                 }
00620                 // TODO init es ref in ctxt
00621             } catch (IndexOutOfBoundsException ex) {
00622                 // pool is empty
00623             }
00624         }
00625 
00626         if (bctx == null) {
00627             // create a new one if pool empty
00628             try {
00629                 bctx = createNewInstance(es);
00630             } catch (Exception e) {
00631                 throw new EJBException("Cannot create a new instance: " + e.toString());
00632             }
00633         }
00634 
00635         // DEBUG
00636         if (bctx.getEntitySwitch() != null) {
00637             TraceEjb.context.log(BasicLevel.ERROR, ejbname + "Context already initialized!");
00638         }
00639 
00640         return bctx;
00641     }
00642 
00647     public void releaseJContext(JContext ctx) {
00648         JEntityContext bctx = (JEntityContext) ctx;
00649         TraceEjb.context.log(BasicLevel.DEBUG, ejbname);
00650         bctx.razEntityContext();
00651         synchronized(bctxlist) {
00652             // debug
00653             if (bctxlist.contains(bctx)) {
00654                 TraceEjb.context.log(BasicLevel.ERROR, ejbname + ": try to put twice this ctx " + bctx);
00655                 Thread.dumpStack();
00656                 return;
00657             }
00658 
00659             bctxlist.add(bctx);
00660         }
00661     }
00662 
00663     // ---------------------------------------------------------------
00664     // other public methods
00665     // ---------------------------------------------------------------
00666 
00671     public TimerService getTimerService() {
00672         return this;
00673     }
00674 
00678     public int getMinPoolSize() {
00679         return minPoolSize;
00680     }
00681 
00685     public int getMaxCacheSize() {
00686         return maxCacheSize;
00687     }
00688 
00692     public int getCacheSize() {
00693         return instanceCount;
00694     }
00695 
00699     public boolean isReentrant() {
00700         return reentrant;
00701     }
00702 
00706     public boolean isShared() {
00707         return shared;
00708     }
00709 
00713     public int lockPolicy() {
00714         return lockPolicy;
00715     }
00716 
00720     public boolean isPrefetch() {
00721         return prefetch;
00722     }
00723 
00727     public Object getDataSource() {
00728         if (datasource == null) {
00729             TraceEjb.logger.log(BasicLevel.ERROR, ejbname + ": datasource not defined in JEntityFactory");
00730         }
00731         return datasource;
00732     }
00733 
00739     public void checkTransaction(RequestCtx rctx) {
00740         checkTransactionContainer(rctx);
00741     }
00742 
00749     public void syncForFind(Transaction tx) {
00750         TraceEjb.interp.log(BasicLevel.DEBUG, ejbname);
00751         if (tx == null) {
00752             if (lockPolicy == EntityDesc.LOCK_CONTAINER_SERIALIZED) {
00753                 sync();
00754             }
00755         } else {
00756             TxListener txl = (TxListener) txlist.get(tx);
00757             if (txl != null) {
00758                 txl.storeInstances();
00759             }
00760         }
00761     }
00762 
00766     public boolean isBlocking(Transaction tx) {
00767         HashMap clone = null;
00768         synchronized (this) {
00769             clone = (HashMap) pklist.clone();
00770         }
00771         JEntitySwitch bs = null;
00772         for (Iterator i = clone.values().iterator(); i.hasNext();) {
00773             bs = (JEntitySwitch) i.next();
00774             Transaction tb = bs.getBlockingTx();
00775             if (tb != null && tb.equals(tx)) {
00776                 return true;
00777             }
00778         }
00779         return false;
00780     }
00781 
00785     public boolean isBlocked(Transaction tx) {
00786         HashMap clone = null;
00787         synchronized (this) {
00788             clone = (HashMap) pklist.clone();
00789         }
00790         JEntitySwitch bs = null;
00791         for (Iterator i = clone.values().iterator(); i.hasNext();) {
00792             bs = (JEntitySwitch) i.next();
00793             Transaction tb = bs.getBlockedTx();
00794             if (tb != null && tb.equals(tx)) {
00795                 return true;
00796             }
00797         }
00798         return false;
00799     }
00800 
00805     public void removeTxListener(Transaction tx) {
00806         TraceEjb.interp.log(BasicLevel.DEBUG, ejbname);
00807         txlist.remove(tx);
00808     }
00809 
00816     public boolean registerContext(Transaction tx, JEntityContext ec) throws IllegalStateException {
00817         TraceEjb.interp.log(BasicLevel.DEBUG, ejbname);
00818 
00819         // Get the TXListener associated to this tx, or create it.
00820         TxListener txl = (TxListener) txlist.get(tx);
00821         if (txl == null) {
00822             txl = new TxListener(this, tx);
00823             // register it as Synchronization.
00824             try {
00825                 tx.registerSynchronization(txl);
00826             } catch (RollbackException e) {
00827                 TraceEjb.logger.log(BasicLevel.WARN, ejbname + " transaction has been marked rollbackOnly");
00828             } catch (SystemException e) {
00829                 TraceEjb.logger.log(BasicLevel.ERROR, ejbname + " cannot register synchro ", e);
00830                 // forget txl.
00831                 throw new IllegalStateException("cannot register synchro");
00832             }
00833             txlist.put(tx, txl);
00834         }
00835 
00836         // Add the JEntityContext
00837         txl.addInstance(ec);
00838         return true;
00839     }
00840 
00845     public synchronized EntityCounters getEntityCounters() {
00846         EntityCounters ec = new EntityCounters();
00847         Collection coll = pklist.values();
00848         for (Iterator i = coll.iterator(); i.hasNext();) {
00849             JEntitySwitch es = (JEntitySwitch) i.next();
00850             switch (es.getState()) {
00851                 case 0:
00852                     ec.inTx++;
00853                     break;
00854                 case 1:
00855                     ec.outTx++;
00856                     break;
00857                 case 2:
00858                     ec.idle++;
00859                     break;
00860                 case 3:
00861                     ec.passive++;
00862                     break;
00863                 case 4:
00864                     ec.removed++;
00865                     break;
00866             }
00867         }
00868         return ec;
00869     }
00870 
00875     public int calculateAutomaticPk() {
00876         TraceEjb.interp.log(BasicLevel.DEBUG, ejbname);
00877         int uid;
00878         synchronized (getClass()) {
00879             uid = (int) (System.currentTimeMillis() % (java.lang.Integer.MAX_VALUE / 10));
00880             uid = uid * 10 + ucount++;
00881         }
00882         return uid;
00883     }
00884 
00891     public void dummyFinderException(boolean dummy) throws FinderException {
00892         if (!dummy) {
00893             throw new FinderException("dummy exception !!!");
00894         }
00895     }
00896 
00901     public void printAllPks() {
00902         if (TraceEjb.isDebugSwapper()) {
00903             HashMap clone = null;
00904             synchronized (this) {
00905                 clone = (HashMap) pklist.clone();
00906             }
00907             JEntitySwitch bs = null;
00908             for (Iterator i = clone.values().iterator(); i.hasNext();) {
00909                 bs = (JEntitySwitch) i.next();
00910                 TraceEjb.swapper.log(BasicLevel.DEBUG, "PK=" + bs.getPrimaryKey());
00911             }
00912         }
00913     }
00914 
00919     private void printMemoryUsage() {
00920         if (TraceEjb.isDebugSwapper()) {
00921             System.gc();
00922             TraceEjb.swapper.log(BasicLevel.DEBUG, 
00923                                  " total = " + Runtime.getRuntime().totalMemory() / 1024 +
00924                                  " free  = " + Runtime.getRuntime().freeMemory() / 1024);
00925         }
00926     }
00927 
00928     // ---------------------------------------------------------------
00929     // private methods
00930     // ---------------------------------------------------------------
00931 
00938     protected JEntityContext createNewInstance(JEntitySwitch es) throws Exception {
00939         TraceEjb.interp.log(BasicLevel.DEBUG, ejbname);
00940 
00941         // create the bean instance
00942         EntityBean bean = null;
00943         try {
00944             bean = (EntityBean) beanclass.newInstance();
00945         } catch (InstantiationException e) {
00946             TraceEjb.logger.log(BasicLevel.ERROR, ejbname + " cannot instantiate bean");
00947             throw e;
00948         } catch (IllegalAccessException e) {
00949             TraceEjb.logger.log(BasicLevel.ERROR, ejbname + " cannot instantiate bean");
00950             throw e;
00951         }
00952 
00953         // create a new EntityContext and bind it to the instance
00954         JEntityContext ec = createNewContext(bean);
00955         bean.setEntityContext(ec);
00956         ec.setState(1);
00957 
00958         // If too many instances, ask swapper to clean memory.
00959         synchronized (this) {
00960             instanceCount++;
00961         }
00962         if (maxCacheSize != 0 && instanceCount > maxCacheSize) {
00963             // Register this factory, if not already done.
00964             if (TraceEjb.isDebugSwapper()) {
00965                 TraceEjb.swapper.log(BasicLevel.DEBUG, ejbname + ": Too many instances :" + instanceCount + ", max="
00966                         + maxCacheSize);
00967             }
00968             cont.registerBF(this);
00969         }
00970 
00971         return ec;
00972     }
00973 
00974     protected JEntityContext createNewContext(EntityBean bean) {
00975         return new JEntityContext(this, bean);
00976     }
00977 
00982     public Serializable encodePK(Serializable pk) {
00983         return pk;
00984     }
00985 
00990     public Serializable decodePK(Serializable strpk) {
00991         return strpk;
00992     }
00993     
00994     /*
00995      * (non-Javadoc)
00996      * @see javax.ejb.TimerService#createTimer(long, java.io.Serializable)
00997      */
00998     public Timer createTimer(long arg0, Serializable arg1) throws IllegalArgumentException, IllegalStateException, EJBException {
00999         throw new IllegalStateException("timer are associated with a PK");
01000     }
01001 
01002     /* (non-Javadoc)
01003      * @see javax.ejb.TimerService#createTimer(long, long, java.io.Serializable)
01004      */
01005     public Timer createTimer(long arg0, long arg1, Serializable arg2) throws IllegalArgumentException, IllegalStateException, EJBException {
01006         throw new IllegalStateException("timer are associated with a PK");
01007     }
01008 
01009     /* (non-Javadoc)
01010      * @see javax.ejb.TimerService#createTimer(java.util.Date, java.io.Serializable)
01011      */
01012     public Timer createTimer(Date arg0, Serializable arg1) throws IllegalArgumentException, IllegalStateException, EJBException {
01013         throw new IllegalStateException("timer are associated with a PK");
01014     }
01015 
01016     /* (non-Javadoc)
01017      * @see javax.ejb.TimerService#createTimer(java.util.Date, long, java.io.Serializable)
01018      */
01019     public Timer createTimer(Date arg0, long arg1, Serializable arg2) throws IllegalArgumentException, IllegalStateException, EJBException {
01020         throw new IllegalStateException("timer are associated with a PK");
01021     }
01022 
01023     /* (non-Javadoc)
01024      * @see javax.ejb.TimerService#getTimers()
01025      */
01026     public Collection getTimers() throws IllegalStateException, EJBException {
01027         throw new IllegalStateException("timer are associated with a PK");
01028     }
01029 
01030 }

Generated on Tue Feb 15 15:05:37 2005 for JOnAS by  doxygen 1.3.9.1