1 package org.apache.ojb.otm.core; 2 3 17 18 import org.apache.ojb.broker.*; 19 import org.apache.ojb.broker.cache.ObjectCache; 20 import org.apache.ojb.broker.core.proxy.ProxyHelper; 21 import org.apache.ojb.broker.accesslayer.OJBIterator; 22 import org.apache.ojb.broker.metadata.ClassDescriptor; 23 import org.apache.ojb.broker.query.Query; 24 import org.apache.ojb.broker.query.ReportQuery; 25 import org.apache.ojb.broker.util.configuration.ConfigurationException; 26 import org.apache.ojb.broker.util.configuration.Configurator; 27 import org.apache.ojb.odmg.oql.EnhancedOQLQuery; 28 import org.apache.ojb.odmg.oql.OQLQueryImpl; 29 import org.apache.ojb.otm.EditingContext; 30 import org.apache.ojb.otm.OTMConnection; 31 import org.apache.ojb.otm.copy.ObjectCopyStrategy; 32 import org.apache.ojb.otm.lock.LockType; 33 import org.apache.ojb.otm.lock.LockingException; 34 import org.odmg.ODMGRuntimeException; 35 import org.odmg.OQLQuery; 36 37 import java.util.Collection ; 38 import java.util.Iterator ; 39 import java.util.ListIterator ; 40 import java.util.ArrayList ; 41 42 51 public abstract class BaseConnection implements OTMConnection 52 { 53 54 private PersistenceBroker _pb; 55 private Transaction _tx; 56 private ConcreteEditingContext _editingContext; 57 private Configurator m_configurator; 58 59 63 public BaseConnection(PBKey pbKey) 64 { 65 _pb = PersistenceBrokerFactory.createPersistenceBroker(pbKey); 66 m_configurator = PersistenceBrokerFactory.getConfigurator(); 67 } 68 69 public void close() 70 { 71 _pb.close(); 72 _pb = null; 73 } 74 75 public boolean isClosed() 76 { 77 if (_pb == null) 78 return true; 79 else 80 return _pb.isClosed(); 81 } 82 83 public PersistenceBroker getKernelBroker() 84 { 85 return _pb; 86 } 87 88 public void setTransaction(Transaction transaction) 89 { 90 if (transaction == null) 91 { 92 _editingContext = null; 93 } 94 else if (_tx != null) 95 { 96 throw new IllegalStateException ("OTMConnection is already bound to the transacaction " 97 + _tx); 98 } 99 else 100 { 101 _editingContext = new ConcreteEditingContext(transaction, _pb); 102 } 103 _tx = transaction; 104 } 105 106 public Transaction getTransaction() 107 { 108 return _tx; 109 } 110 111 115 118 public Object getObjectByIdentity(Identity oid, int lock) throws LockingException 119 { 120 checkTransaction("getObjectByIdentity"); 121 Object userObject; 122 Object cacheObject; 123 124 cacheObject = _pb.getObjectByIdentity(oid); 125 if (cacheObject == null) 126 { 127 userObject = _editingContext.lookup(oid); 130 } 131 else 132 { 133 userObject = getUserObject(oid, cacheObject); 134 userObject = ProxyHelper.getRealObject(userObject); 136 _editingContext.insert(oid, userObject, lock); 137 } 138 return userObject; 139 } 140 141 private void checkTransaction(String methodBeingCalled) 142 { 143 if (null == _tx) 144 { 145 throw new TransactionNotInProgressException( 146 methodBeingCalled 147 + " requires a valid transaction. Please make sure you have created a new transaction, and called begin() on it."); 148 } 149 if (!_tx.isInProgress()) 150 { 151 throw new TransactionNotInProgressException(methodBeingCalled 152 + " cannot be called before transaction begin() is called"); 153 } 154 } 155 156 159 public Object getObjectByIdentity(Identity oid) throws LockingException 160 { 161 return getObjectByIdentity(oid, LockType.READ_LOCK); 162 } 163 164 168 public Iterator getIteratorByQuery(Query query) 169 { 170 return getIteratorByQuery(query, LockType.READ_LOCK); 171 } 172 173 184 public Iterator getIteratorByQuery(Query query, int lock) 185 { 186 checkTransaction("getIteratorByQuery"); 187 return new OTMIterator((OJBIterator) _pb.getIteratorByQuery(query), lock, null); 188 } 189 190 195 public Iterator getIteratorByOQLQuery(OQLQuery query) 196 { 197 return getIteratorByOQLQuery(query, LockType.READ_LOCK); 198 } 199 200 205 public Iterator getIteratorByOQLQuery(OQLQuery query, int lock) 206 { 207 checkTransaction("getIteratorByOQLQuery"); 208 if (query instanceof OTMOQLQueryImpl) 209 { 210 OTMOQLQueryImpl q = (OTMOQLQueryImpl) query; 211 return new OTMIterator((OJBIterator) _pb.getIteratorByQuery(q.getQuery()), lock, q); 212 } 213 else 214 { 215 throw new IllegalArgumentException ("The OQLQuery where created not via OTM API"); 216 } 217 } 218 219 230 public Collection getCollectionByQuery(Query query, int lock) 231 { 232 checkTransaction("getCollectionByQuery"); 233 Collection col = _pb.getCollectionByQuery(query); 234 Collection result = createCollectionOfTheSameClass(col); 235 for (Iterator it = col.iterator(); it.hasNext();) 236 { 237 result.add(insertObject(it.next(), lock)); 238 } 239 return result; 240 } 241 242 247 public Collection getCollectionByQuery(Query query) 248 { 249 return getCollectionByQuery(query, LockType.READ_LOCK); 250 } 251 252 258 public Identity getIdentity(Object object) 259 { 260 return new Identity(object, _pb); 261 } 262 263 269 public ClassDescriptor getDescriptorFor(Class clazz) 270 { 271 return _pb.getClassDescriptor(clazz); 272 } 273 274 277 public void invalidate(Identity oid) throws LockingException 278 { 279 if (null == _tx) 280 { 281 throw new TransactionNotInProgressException( 282 "invalidate requires a valid transaction. Please make sure you have created a new transaction, and called begin() on it."); 283 } 284 _editingContext.insert(oid, null, LockType.READ_LOCK); 286 287 _pb.serviceObjectCache().remove(oid); 289 290 } 291 292 295 public ObjectCache serviceObjectCache() 296 { 297 return _pb.serviceObjectCache(); 298 } 299 300 305 public void invalidateAll() throws LockingException 306 { 307 _pb.serviceObjectCache().clear(); 308 } 309 310 313 public void lockForWrite(Object object) throws LockingException 314 { 315 checkTransaction("lockForWrite"); 316 makePersistent(object); 317 } 318 319 322 public void makePersistent(Object userObject) throws LockingException 323 { 324 checkTransaction("makePersistent"); 325 Identity oid = new Identity(userObject, _pb); 326 Object cacheObject = _pb.getObjectByIdentity(oid); 327 328 if ((cacheObject != null) && (_editingContext.lookup(oid) == null)) 329 { 330 ObjectCopyStrategy copyStrategy = _tx.getKit().getCopyStrategy(oid); 335 Object origUserObject = copyStrategy.copy(cacheObject, _pb); 336 _editingContext.insert(oid, origUserObject, LockType.WRITE_LOCK); 337 } 338 _editingContext.insert(oid, userObject, LockType.WRITE_LOCK); 339 } 340 341 344 public void deletePersistent(Object userObject) throws LockingException 345 { 346 checkTransaction("deletePersistent"); 347 Identity oid = new Identity(userObject, _pb); 348 Object cacheObject = _pb.getObjectByIdentity(oid); 349 if (cacheObject == null) 350 { 351 _editingContext.remove(oid); 355 } 356 else 357 { 358 if (_editingContext.lookup(oid) == null) 359 { 360 ObjectCopyStrategy copyStrategy = _tx.getKit().getCopyStrategy(oid); 363 Object origUserObject = copyStrategy.copy(cacheObject, _pb); 364 _editingContext.insert(oid, origUserObject, LockType.WRITE_LOCK); 365 } 366 _editingContext.deletePersistent(oid, userObject); 367 } 368 } 369 370 373 public void refresh(Object userObject) 374 { 375 checkTransaction("refresh"); 376 Identity oid = new Identity(userObject, _pb); 377 _editingContext.refresh(oid, userObject); 378 } 379 380 public EditingContext getEditingContext() 381 { 382 return _editingContext; 383 } 384 385 public EnhancedOQLQuery newOQLQuery() 386 { 387 return newOQLQuery(LockType.READ_LOCK); 388 } 389 390 public EnhancedOQLQuery newOQLQuery(int lock) 391 { 392 checkTransaction("newOQLQuery"); 393 OQLQueryImpl query = new OTMOQLQueryImpl(_pb.getPBKey(), lock); 394 try 395 { 396 m_configurator.configure(query); 397 } 398 catch (ConfigurationException e) 399 { 400 throw new ODMGRuntimeException("Error in configuration of OQLQueryImpl instance: " 401 + e.getMessage()); 402 } 403 return query; 404 } 405 406 public int getCount(Query query) 407 { 408 checkTransaction("getCount"); 409 return _pb.getCount(query); 410 } 411 412 private Object insertObject(Object cacheObject, int lock) 413 { 414 Object ctxObject; 415 Identity oid; 416 Object userObject; 417 418 419 oid = getIdentity(cacheObject); 420 userObject = getUserObject(oid, cacheObject); 421 try 422 { 423 _editingContext.insert(oid, userObject, lock); 424 } 425 catch (LockingException ex) 426 { 427 throw new LockingPassthruException(ex); 428 } 429 430 return userObject; 431 } 432 433 440 private Object getUserObject(Identity oid, Object cacheObject) 441 { 442 Object userObject = _editingContext.lookup(oid); 443 444 if (userObject == null) 445 { 446 ObjectCopyStrategy copyStrategy = _tx.getKit().getCopyStrategy(oid); 447 userObject = copyStrategy.copy(cacheObject, _pb); 448 } 449 return userObject; 450 } 451 452 private Collection createCollectionOfTheSameClass(Collection col) 453 { 454 try 455 { 456 return (Collection ) col.getClass().newInstance(); 457 } 458 catch (Throwable ex) 459 { 460 return new ArrayList (); 461 } 462 } 463 464 468 473 public abstract void transactionBegin() throws TransactionException; 474 475 480 public abstract void transactionPrepare() throws TransactionException; 481 482 487 public abstract void transactionCommit() throws TransactionException; 488 489 495 public abstract void transactionRollback() throws TransactionException; 496 497 501 private class OTMIterator implements OJBIterator 502 { 503 private final OJBIterator _it; 504 private final int _lock; 505 private final OTMOQLQueryImpl _oqlQuery; 506 507 OTMIterator(OJBIterator it, int lock, OTMOQLQueryImpl oqlQuery) 508 { 509 _it = it; 510 _lock = lock; 511 _oqlQuery = oqlQuery; 512 } 513 514 public boolean hasNext() 515 { 516 boolean res = _it.hasNext(); 517 518 if (!res) 520 { 521 done(); 522 } 523 524 return res; 525 } 526 527 public Object next() 528 { 529 Object object = _it.next(); 530 object = insertObject(object, _lock); 531 return object; 532 } 533 534 public void remove() 535 { 536 throw new UnsupportedOperationException (); 537 } 538 539 public void done() 540 { 541 releaseDbResources(); 542 if (_oqlQuery != null) 543 { 544 _oqlQuery.resetBindIterator(); 545 } 546 } 547 548 protected void finalize() 549 { 550 done(); 551 } 552 553 558 public boolean absolute(int row) throws PersistenceBrokerException 559 { 560 return _it.absolute(row); 561 } 562 563 568 public int fullSize() throws PersistenceBrokerException 569 { 570 return _it.fullSize(); 571 } 572 573 578 public boolean relative(int row) throws PersistenceBrokerException 579 { 580 return _it.relative(row); 581 } 582 583 588 public void releaseDbResources() 589 { 590 _it.releaseDbResources(); 591 } 592 593 598 public int size() throws PersistenceBrokerException 599 { 600 return _it.size(); 601 } 602 603 606 public void disableLifeCycleEvents() 607 { 608 _it.disableLifeCycleEvents(); 609 } 610 } 611 612 private class OTMOQLQueryImpl extends OQLQueryImpl 613 { 614 int _lock; 615 616 public OTMOQLQueryImpl(PBKey key, int lock) 617 { 618 super(key); 619 _lock = lock; 620 } 621 622 632 public Object execute() throws org.odmg.QueryException 633 { 634 Collection result; 635 Iterator iter = null; 636 Query query = getQuery(); 637 638 try 639 { 640 if (!(query instanceof ReportQuery)) 641 { 642 Collection res0 = _pb.getCollectionByQuery(query); 643 result = createCollectionOfTheSameClass(res0); 644 for (iter = res0.iterator(); iter.hasNext();) 645 { 646 result.add(insertObject(iter.next(), _lock)); 647 } 648 } 649 else 650 { 651 result = new ArrayList (); 652 iter = _pb.getReportQueryIteratorByQuery(query); 653 while (iter.hasNext()) 654 { 655 Object [] res = (Object []) iter.next(); 656 657 if (res.length == 1) 658 { 659 if (res[0] != null) { 661 result.add(res[0]); 662 } 663 } 664 else 665 { 666 for (int i = 0; i < res.length; i++) 668 { 669 if (res[i] != null) 670 { 671 result.add(res); 672 break; 673 } 674 } 675 } 676 } 677 } 678 resetBindIterator(); 679 } 680 finally 681 { 682 if ((iter != null) && (iter instanceof OJBIterator)) 683 { 684 ((OJBIterator) iter).releaseDbResources(); 685 } 686 } 687 return result; 688 } 689 690 void resetBindIterator() 691 { 692 ListIterator it = getBindIterator(); 694 while (it.hasPrevious()) 695 { 696 it.previous(); 697 } 698 } 699 } 700 701 } 702 | Popular Tags |