00001
00026 package org.objectweb.jonas_ejb.container;
00027
00028 import java.rmi.RemoteException;
00029
00030 import javax.ejb.EJBException;
00031 import javax.ejb.EJBLocalObject;
00032 import javax.ejb.EJBObject;
00033 import javax.ejb.EntityBean;
00034 import javax.ejb.EntityContext;
00035 import javax.ejb.NoSuchObjectLocalException;
00036 import javax.ejb.RemoveException;
00037 import javax.ejb.TimerService;
00038 import javax.transaction.Status;
00039 import javax.transaction.Synchronization;
00040 import javax.transaction.SystemException;
00041 import javax.transaction.Transaction;
00042
00043 import org.objectweb.jonas_ejb.deployment.api.EntityDesc;
00044
00045 import org.objectweb.util.monolog.api.BasicLevel;
00046
00055 public class JEntityContext extends JContext implements EntityContext, Synchronization {
00056
00060 private boolean dirty = false;
00061
00065 Transaction beanCoord = null;
00066
00067 private boolean mustnotifywriting = false;
00068
00069 private JEntitySwitch bs = null;
00070
00074 boolean ismarkedremoved;
00075
00079 boolean isnewinstance = false;
00080
00081
00082
00083
00084
00090 public JEntityContext(JEntityFactory bf, EntityBean eb) {
00091 super(bf, eb);
00092
00093 this.home = bf.getHome();
00094 this.localhome = bf.getLocalHome();
00095 }
00096
00097
00098
00099
00100
00107 public TimerService getTimerService() throws IllegalStateException {
00108 int mystate = getState();
00109 TraceEjb.interp.log(BasicLevel.DEBUG, "" + mystate);
00110 switch (mystate) {
00111 case 0:
00112 TraceEjb.logger.log(BasicLevel.ERROR, "not allowed here");
00113 throw new IllegalStateException("getTimerService not allowed here");
00114 case 4:
00115 TraceEjb.logger.log(BasicLevel.ERROR, "not allowed here");
00116 throw new IllegalStateException("getTimerService not allowed here");
00117 case 1:
00118
00119
00120
00121 return bf.getTimerService();
00122 default:
00123 return bs == null ? bf.getTimerService() : bs.getEntityTimerService();
00124 }
00125 }
00126
00127
00128
00129
00130
00139 public EJBObject getEJBObject() throws IllegalStateException {
00140 TraceEjb.interp.log(BasicLevel.DEBUG, "");
00141 if (ismarkedremoved) {
00142 TraceEjb.logger.log(BasicLevel.ERROR, "marked removed");
00143 throw new IllegalStateException("EJB is removed");
00144 }
00145 if (bs == null) {
00146 TraceEjb.logger.log(BasicLevel.ERROR, "no EntitySwitch");
00147 throw new IllegalStateException("no EntitySwitch");
00148 }
00149 EJBObject ejbobject = bs.getRemote();
00150 if (ejbobject == null) {
00151 throw new IllegalStateException("No Remote Interface for this bean");
00152 }
00153 return ejbobject;
00154 }
00155
00166 private EJBLocalObject getEJBLocalObject(boolean check) throws IllegalStateException {
00167 TraceEjb.interp.log(BasicLevel.DEBUG, "");
00168 if (check) {
00169 if (!bf.dd.hasDefinedLocalInterface()) {
00170 TraceEjb.logger.log(BasicLevel.ERROR, "No Local Interface declared for this bean");
00171 throw new IllegalStateException("No Local Interface declared for this bean");
00172 }
00173 }
00174 if (ismarkedremoved) {
00175 TraceEjb.logger.log(BasicLevel.ERROR, "marked removed");
00176 throw new IllegalStateException("EJB is removed");
00177 }
00178 if (bs == null) {
00179 TraceEjb.logger.log(BasicLevel.ERROR, "no EntitySwitch");
00180 throw new IllegalStateException("no EntitySwitch");
00181 }
00182 EJBLocalObject ejblocalobject = bs.getLocal();
00183 if (ejblocalobject == null) {
00184 throw new IllegalStateException("No Local Object for this bean");
00185 }
00186 return ejblocalobject;
00187 }
00188
00198 public EJBLocalObject getEJBLocalObject() throws IllegalStateException {
00199 return getEJBLocalObject(true);
00200 }
00201
00212 public EJBLocalObject get2EJBLocalObject() throws IllegalStateException {
00213 return getEJBLocalObject(false);
00214 }
00215
00224 public Object getPrimaryKey() throws IllegalStateException {
00225 TraceEjb.interp.log(BasicLevel.DEBUG, "");
00226 if (ismarkedremoved) {
00227 TraceEjb.logger.log(BasicLevel.ERROR, "marked removed");
00228 throw new IllegalStateException("EJB is removed");
00229 }
00230 if (bs == null) {
00231 TraceEjb.logger.log(BasicLevel.ERROR, "no EntitySwitch");
00232 throw new IllegalStateException("no EntitySwitch");
00233 }
00234 return bs.getPrimaryKey();
00235 }
00236
00237
00238
00239
00240
00244 public void beforeCompletion() {
00245 TraceEjb.context.log(BasicLevel.DEBUG, "");
00246
00247
00248 if (ismarkedremoved) {
00249 TraceEjb.context.log(BasicLevel.DEBUG, "ismarkedremoved -> no ejbStore");
00250 return;
00251 }
00252
00253 if (beanCoord == null) {
00254
00255 TraceEjb.logger.log(BasicLevel.ERROR, "no tx");
00256 }
00257
00258
00259
00260 if (isnewinstance) {
00261 try {
00262 if (getPrimaryKey() == null) {
00263
00264
00265
00266
00267 return;
00268 }
00269 } catch (IllegalStateException e) {
00270 return;
00271 }
00272 }
00273
00274 try {
00275 storeIfModified();
00276 } catch (EJBException e) {
00277
00278 abortTransaction();
00279 }
00280 }
00281
00286 public void afterCompletion(int status) {
00287
00288 boolean committed = (status == Status.STATUS_COMMITTED);
00289 if (committed) {
00290 TraceEjb.context.log(BasicLevel.DEBUG, "committed");
00291 } else {
00292 TraceEjb.context.log(BasicLevel.DEBUG, "rolledback");
00293 }
00294
00295
00296 if (beanCoord == null) {
00297
00298 TraceEjb.logger.log(BasicLevel.ERROR, "no tx for " + this);
00299 return;
00300 }
00301
00302 if (bs == null) {
00303
00304 TraceEjb.logger.log(BasicLevel.ERROR, "Context without EntitySwitch reference");
00305 throw new EJBException("Context with no Entity Switch");
00306 }
00307
00308
00309
00310
00311 bs.txCompleted(beanCoord, committed);
00312 }
00313
00314
00315
00316
00317
00321 public void razEntityContext() {
00322 TraceEjb.context.log(BasicLevel.DEBUG, "");
00323 bs = null;
00324 beanCoord = null;
00325 ismarkedremoved = false;
00326 isnewinstance = false;
00327 }
00328
00332 public void detachTx() {
00333 TraceEjb.context.log(BasicLevel.DEBUG, "");
00334 beanCoord = null;
00335 ismarkedremoved = false;
00336 isnewinstance = false;
00337 }
00338
00343 public void initEntityContext(JEntitySwitch bs) {
00344 TraceEjb.context.log(BasicLevel.DEBUG, "");
00345 this.bs = bs;
00346 ismarkedremoved = false;
00347 mustnotifywriting = (bs.getPolicy() == EntityDesc.LOCK_CONTAINER_READ_UNCOMMITTED || bs.getPolicy() == EntityDesc.LOCK_DATABASE);
00348 }
00349
00350 public void setRunningTx(Transaction tx) {
00351 TraceEjb.context.log(BasicLevel.DEBUG, "");
00352 beanCoord = tx;
00353 }
00354
00360 public void reuseEntityContext(boolean newtrans) {
00361 TraceEjb.context.log(BasicLevel.DEBUG, "");
00362
00363
00364 if (ismarkedremoved) {
00365 TraceEjb.context.log(BasicLevel.WARN, "Try to access a deleted object");
00366 throw new NoSuchObjectLocalException("Instance has been removed");
00367 }
00368 if (newtrans) {
00369 isnewinstance = false;
00370 }
00371 if (bs == null) {
00372 TraceEjb.logger.log(BasicLevel.ERROR, "reuse Entity Context with no Entity Switch reference");
00373 }
00374 }
00375
00379 public void setNewInstance() {
00380 isnewinstance = true;
00381 }
00382
00389 public void setRemoved() throws RemoteException, RemoveException {
00390 TraceEjb.context.log(BasicLevel.DEBUG, "");
00391 EntityBean eb = (EntityBean) instance;
00392
00393 if (instance == null) {
00394 TraceEjb.logger.log(BasicLevel.ERROR, "null instance!");
00395 return;
00396 }
00397
00398 eb.ejbRemove();
00399
00400
00401 ismarkedremoved = true;
00402 }
00403
00408 public boolean isMarkedRemoved() {
00409 return ismarkedremoved;
00410 }
00411
00416 public boolean isNewInstance() {
00417 return isnewinstance;
00418 }
00419
00426
00427 public EntityBean getInstance() throws RemoteException {
00428 if (instance == null) {
00429 TraceEjb.logger.log(BasicLevel.ERROR, "null!");
00430 throw new RemoteException("No instance available");
00431 }
00432 return (EntityBean) instance;
00433 }
00434
00439 public JEntityFactory getEntityFactory() {
00440 return (JEntityFactory) bf;
00441 }
00442
00447 public JEntitySwitch getEntitySwitch() {
00448 return (JEntitySwitch) bs;
00449 }
00450
00455 public void setEntitySwitch(JEntitySwitch bs) {
00456 this.bs = bs;
00457 }
00458
00462 public boolean isDirty() {
00463 return dirty;
00464 }
00465
00469 public void setDirty(boolean d) {
00470
00471 if (mustnotifywriting && d && !dirty) {
00472
00473 Transaction tx = null;
00474 try {
00475 tx = tm.getTransaction();
00476 } catch (SystemException e) {
00477 TraceEjb.context.log(BasicLevel.ERROR, "getTransaction failed:" + e);
00478 }
00479 if (tx == null) {
00480 TraceEjb.context.log(BasicLevel.DEBUG, "Try to modify bean outside any transaction");
00481 } else {
00482 bs.notifyWriting(tx, this);
00483 }
00484 }
00485 dirty = d;
00486 }
00487
00491 public void storeIfModified() {
00492
00493 EntityBean eb = (EntityBean) instance;
00494
00495 if (ismarkedremoved) {
00496
00497 TraceEjb.context.log(BasicLevel.DEBUG, "marked removed");
00498 return;
00499 }
00500 TraceEjb.context.log(BasicLevel.DEBUG, "");
00501
00502 try {
00503
00504
00505
00506 eb.ejbStore();
00507 } catch (RemoteException e) {
00508 throw new EJBException("Exception while storing data");
00509 } catch (EJBException e) {
00510 TraceEjb.logger.log(BasicLevel.ERROR, "raised EJBException ", e);
00511 throw e;
00512 } catch (RuntimeException e) {
00513 TraceEjb.logger.log(BasicLevel.ERROR, "runtime exception: ", e);
00514 throw new EJBException("Exception while storing data", e);
00515 } catch (Error e) {
00516 TraceEjb.logger.log(BasicLevel.ERROR, "error: ", e);
00517 throw new EJBException("Error while storing data");
00518 }
00519 }
00520
00524 public void passivate() {
00525
00526 TraceEjb.context.log(BasicLevel.DEBUG, "");
00527
00528 EntityBean eb = (EntityBean) instance;
00529 setState(1);
00530
00531 try {
00532 eb.ejbPassivate();
00533 } catch (Exception e) {
00534 TraceEjb.logger.log(BasicLevel.ERROR, "ejbPassivate failed", e);
00535 } catch (Error e) {
00536 TraceEjb.logger.log(BasicLevel.ERROR, "ejbPassivate error", e);
00537 }
00538 }
00539
00544 public void activate(boolean doactivate) {
00545 TraceEjb.context.log(BasicLevel.DEBUG, "");
00546
00547 EntityBean eb = (EntityBean) instance;
00548
00549 try {
00550 if (doactivate) {
00551 setState(1);
00552
00553 eb.ejbActivate();
00554 }
00555 setState(2);
00556
00557 eb.ejbLoad();
00558 } catch (RemoteException e) {
00559 TraceEjb.logger.log(BasicLevel.ERROR, "remote exception: ", e);
00560 throw new EJBException("Cannot activate bean");
00561 } catch (RuntimeException e) {
00562 TraceEjb.logger.log(BasicLevel.ERROR, "runtime exception: ", e);
00563 throw new EJBException("Cannot activate bean");
00564 } catch (Error e) {
00565 TraceEjb.logger.log(BasicLevel.ERROR, "error: ", e);
00566 throw new EJBException("Cannot activate bean");
00567 }
00568 }
00569
00570
00571
00572
00573
00578 private void abortTransaction() {
00579 TraceEjb.context.log(BasicLevel.DEBUG, "");
00580
00581
00582 if (beanCoord != null) {
00583 try {
00584 beanCoord.setRollbackOnly();
00585 } catch (SystemException e) {
00586 TraceEjb.logger.log(BasicLevel.ERROR, "cannot setRollbackOnly");
00587 }
00588 }
00589 }
00590
00591 }