1 30 package com.genimen.djeneric.repository; 31 32 import java.util.HashMap ; 33 34 import com.genimen.djeneric.language.Messages; 35 import com.genimen.djeneric.repository.exceptions.CatalogException; 36 import com.genimen.djeneric.repository.exceptions.DjenericException; 37 import com.genimen.djeneric.repository.exceptions.ObjectNotDefinedException; 38 import com.genimen.djeneric.repository.exceptions.RestrictionFailedException; 39 import com.genimen.djeneric.util.DjLogger; 40 41 50 public abstract class DjSession 51 { 52 57 public abstract void commit() throws DjenericException; 58 59 62 public abstract void close(); 63 64 77 public abstract void releaseDatasources(); 78 79 82 public abstract DjObject createObject(DjExtent extent) throws DjenericException; 83 84 95 public abstract DjObject getObject(DjExtent extent, long id) throws DjenericException; 96 97 105 public abstract DjList getObjects(DjExtent extent, boolean forceReloadFromDB) throws DjenericException; 106 107 118 public abstract DjList getObjects(DjObjectMatcher matcher, boolean forceReloadFromDB) throws DjenericException; 119 120 131 public abstract DjCursor getObjectsCursor(DjExtent ext, boolean forceReloadFromDB) throws DjenericException; 132 133 144 public abstract DjCursor getObjectsCursor(DjObjectMatcher matcher, boolean forceReloadFromDB) 145 throws DjenericException; 146 147 protected abstract void addValidMasterObjects(DjExtent masterExtent, long restrictingOid, 148 String restrictingPropertyName, boolean forceReloadFromDB, 149 DjList results) throws DjenericException; 150 151 153 DjPersistenceManager _mgr; 154 HashMap _registeredValidValueLists = new HashMap (); 155 156 boolean _invalid = false; 157 DjList _modifiedObjects = new DjList(); 158 DjObjectCache _sessionCache = new DjObjectCache(); 159 boolean _validateObjectsAfterLoading = true; 160 161 private boolean _commitAllowed = true; 162 private long _nextTransientObjectId; 163 private Boolean _canCreate = null; 164 private Boolean _canDelete = null; 165 private Boolean _canModify = null; 166 private Boolean _canQuery = null; 167 168 174 protected DjSession(DjPersistenceManager mgr) 175 { 176 _mgr = mgr; 177 if (shouldTrace(DjPersistenceManager.TRACE_FLOW)) trace("Session created"); 178 } 179 180 public boolean canCreate() throws DjenericException 181 { 182 if (_canCreate == null) 183 { 184 DjContext ctxt = getPersistenceManager().getCurrentContext(); 185 DjUser user = getPersistenceManager().getCurrentUser(); 186 _canCreate = new Boolean (user.canCreate(ctxt)); 187 } 188 return _canCreate.booleanValue(); 189 } 190 191 public boolean canDelete() throws DjenericException 192 { 193 if (_canDelete == null) 194 { 195 DjContext ctxt = getPersistenceManager().getCurrentContext(); 196 DjUser user = getPersistenceManager().getCurrentUser(); 197 _canDelete = new Boolean (user.canDelete(ctxt)); 198 } 199 return _canDelete.booleanValue(); 200 } 201 202 public boolean canModify() throws DjenericException 203 { 204 if (_canModify == null) 205 { 206 DjContext ctxt = getPersistenceManager().getCurrentContext(); 207 DjUser user = getPersistenceManager().getCurrentUser(); 208 _canModify = new Boolean (user.canModify(ctxt)); 209 } 210 return _canModify.booleanValue(); 211 } 212 213 public boolean canQuery() throws DjenericException 214 { 215 if (_canQuery == null) 216 { 217 DjContext ctxt = getPersistenceManager().getCurrentContext(); 218 DjUser user = getPersistenceManager().getCurrentUser(); 219 _canQuery = new Boolean (user.canQuery(ctxt)); 220 } 221 return _canQuery.booleanValue(); 222 } 223 224 233 public DjQueryByExample createQueryByExample(DjExtent extent) throws DjenericException 234 { 235 return new DjQueryByExample(this, extent); 236 } 237 238 252 public DjOql createOql(DjExtent extent) 253 { 254 return new DjOql(extent); 255 } 256 257 271 public DjOql createOql(DjExtent extent, String whereExpression) 272 { 273 return new DjOql(extent, whereExpression); 274 } 275 276 284 public DjQueryByExample createQueryByExample(String objectType) throws DjenericException 285 { 286 return new DjQueryByExample(this, objectType); 287 } 288 289 296 public void setCommitAllowed(boolean b) 297 { 298 _commitAllowed = b; 299 } 300 301 304 public boolean isCommitAllowed() 305 { 306 return _commitAllowed; 307 } 308 309 316 public void setValidateObjectsAfterLoading(boolean b) 317 { 318 _validateObjectsAfterLoading = b; 319 } 320 321 324 public boolean shouldValidateObjectsAfterLoading() 325 { 326 return _validateObjectsAfterLoading; 327 } 328 329 332 public boolean isValid() 333 { 334 return !_invalid; 335 } 336 337 341 public void setValid(boolean b) 342 { 343 _invalid = !b; 344 } 345 346 351 protected DjList getModifiedObjects() 352 { 353 return _modifiedObjects; 354 } 355 356 361 public DjPersistenceManager getPersistenceManager() 362 { 363 return _mgr; 364 } 365 366 369 public void trace(String msg) 370 { 371 _mgr.trace(msg); 372 } 373 374 378 public boolean shouldTrace(int level) 379 { 380 return _mgr.shouldTrace(level); 381 } 382 383 389 public void reset() 390 { 391 393 _modifiedObjects.clear(); 394 _sessionCache.clear(); 395 if (shouldTrace(DjPersistenceManager.TRACE_INTERNAL)) trace("Session reset"); 396 } 397 398 401 public void cacheObject(DjObject po) throws DjenericException 402 { 403 if (_invalid) throw new DjenericException(Messages.getString("global.SessionClosed")); 404 _sessionCache.cache(po); 405 } 406 407 private void addToModifiedList(DjObject po) throws DjenericException 408 { 409 if (_invalid) throw new DjenericException(Messages.getString("global.SessionClosed")); 410 if (!_modifiedObjects.contains(po)) _modifiedObjects.add(po); 411 cacheObject(po); 412 } 413 414 private void removeFromModifiedList(DjObject po) throws DjenericException 415 { 416 _modifiedObjects.remove(po); 417 cacheObject(po); 419 } 420 421 430 public void unregisterDjenericObject(DjObject po) throws DjenericException 431 { 432 if (_invalid) throw new DjenericException(Messages.getString("global.SessionClosed")); 433 434 removeFromModifiedList(po); 435 _sessionCache.remove(po); 436 } 437 438 447 public DjList getObjects(String extentName) throws DjenericException 448 { 449 return getObjects(_mgr.getExtent(extentName)); 450 } 451 452 461 public DjList getObjects(DjExtent extent) throws DjenericException 462 { 463 return getObjects(extent, false); 464 } 465 466 475 public DjList getObjects(DjObjectMatcher matcher) throws DjenericException 476 { 477 return getObjects(matcher, false); 478 } 479 480 489 public DjCursor getObjectsCursor(DjExtent ext) throws DjenericException 490 { 491 return getObjectsCursor(ext, false); 492 } 493 494 503 public DjCursor getObjectsCursor(DjObjectMatcher matcher) throws DjenericException 504 { 505 return getObjectsCursor(matcher, false); 506 } 507 508 protected DjDomainValue[] getValidValues(String listKey) 509 { 510 return (DjDomainValue[]) _registeredValidValueLists.get(listKey); 511 } 512 513 protected void registerValidValues(String listKey, DjDomainValue[] valids) 514 { 515 _registeredValidValueLists.put(listKey, valids); 516 } 517 518 521 public void resetValidValueLists() 522 { 523 _registeredValidValueLists.clear(); 524 } 525 526 533 protected void updateDetailFlags() throws DjenericException 534 { 535 for (int i = 0; i < getModifiedObjects().size(); i++) 536 { 537 DjObject po = getModifiedObjects().getDjenericObjectAt(i); 538 po.setIsDetail(false); 539 } 541 542 for (int i = 0; i < getModifiedObjects().size(); i++) 543 { 544 DjObject po = getModifiedObjects().getDjenericObjectAt(i); 545 po.updateDetailFlags(); 546 } 547 } 548 549 protected void updateDetailOfnewMasterFlags() throws DjenericException 550 { 551 for (int i = 0; i < getModifiedObjects().size(); i++) 552 { 553 DjObject po = getModifiedObjects().getDjenericObjectAt(i); 554 po.setDetailOfNewMaster(false); 555 } 557 558 for (int i = 0; i < getModifiedObjects().size(); i++) 559 { 560 DjObject po = getModifiedObjects().getDjenericObjectAt(i); 561 po.updateDetailOfnewMasterFlags(); 562 } 563 } 564 565 protected void addModifiedObjectsFromSession(DjExtent thisType, DjObjectMatcher matcher, DjList toThisList, 566 boolean deletedObjectsToo) throws DjenericException 567 { 568 for (int i = 0; i < getModifiedObjects().size(); i++) 569 { 570 DjObject po = getModifiedObjects().getDjenericObjectAt(i); 571 572 if (po.getExtent() == thisType && po.isModified()) 574 { 575 if (deletedObjectsToo || !po.isMarkedForDelete()) 576 { 577 boolean canAdd = true; 578 if (matcher != null) 579 { 580 if (!matcher.match(po)) canAdd = false; 581 } 582 if (canAdd) toThisList.add(po); 583 } 584 } 585 } 586 587 DjExtent specs[] = thisType.getSpecializations(); 588 for (int i = 0; i < specs.length; i++) 589 { 590 addModifiedObjectsFromSession(specs[i], matcher, toThisList, deletedObjectsToo); 591 } 592 } 593 594 protected void addNewObjectsFromSession(DjExtent extent, String restrictingPropertyName, long restrictingOid, 595 DjList toThisList) throws DjenericException 596 { 597 int propIdx = extent.getPropertyIndex(restrictingPropertyName); 598 599 for (int i = 0; i < getModifiedObjects().size(); i++) 600 { 601 DjObject po = getModifiedObjects().getDjenericObjectAt(i); 602 if (po.getExtent() == extent && po.isNew() && po.getLong(propIdx) == restrictingOid) 603 { 604 toThisList.add(po); 605 } 606 } 607 DjExtent specs[] = extent.getSpecializations(); 608 for (int i = 0; i < specs.length; i++) 609 { 610 addNewObjectsFromSession(specs[i], restrictingPropertyName, restrictingOid, toThisList); 611 } 612 } 613 614 private void addDetailsFromSession(long masterObjectId, DjExtent detailExtent, int detailPropIdx, DjList toThisList, 615 boolean onlyNewObjects) throws DjenericException 616 { 617 for (int i = 0; i < getModifiedObjects().size(); i++) 618 { 619 DjObject po = getModifiedObjects().getDjenericObjectAt(i); 620 if (po.getExtent() == detailExtent && (!onlyNewObjects || !po.isNew()) 621 && po.getLong(detailPropIdx) == masterObjectId && !po.isMarkedForDelete()) 622 { 623 toThisList.add(po); 624 } 625 } 626 DjExtent specs[] = detailExtent.getSpecializations(); 627 for (int i = 0; i < specs.length; i++) 628 { 629 addDetailsFromSession(masterObjectId, specs[i], detailPropIdx, toThisList, onlyNewObjects); 630 } 631 } 632 633 private void addDetailsFromSession(DjObject master, DjRelation rel, DjExtent specificType, DjList toThisList, 634 boolean newObjectsOnly) throws DjenericException 635 { 636 if (!specificType.isInstanceof(rel.getDetailExtent())) throw new DjenericException("Internal error: " 637 + specificType.getName() 638 + " is not a " 639 + rel.getDetailExtent() 640 .getName()); 641 int detailPropIdx = specificType.getPropertyIndex(rel.getDetailProperty().getName()); 642 long masterObjectId = master.getObjectId(); 643 644 addDetailsFromSession(masterObjectId, specificType, detailPropIdx, toThisList, newObjectsOnly); 645 } 646 647 protected void addNewDetailsFromSession(DjObject master, DjRelation rel, DjExtent specificType, DjList toThisList) 648 throws DjenericException 649 { 650 addDetailsFromSession(master, rel, specificType, toThisList, true); 651 } 652 653 protected void addDetailsFromSession(DjObject master, DjRelation rel, DjExtent specificType, DjList toThisList) 654 throws DjenericException 655 { 656 addDetailsFromSession(master, rel, specificType, toThisList, false); 657 } 658 659 664 public boolean hasOutstandingChanges() 665 { 666 for (int i = 0; i < getModifiedObjects().size(); i++) 667 { 668 DjObject po = getModifiedObjects().getDjenericObjectAt(i); 669 if (po.isModified() || po.isMarkedForDelete()) return true; 670 } 671 return false; 672 } 673 674 680 681 protected void postChanges() throws DjenericException 682 { 683 if (shouldTrace(DjPersistenceManager.TRACE_FLOW)) trace("Session post commenced"); 684 if (!isValid()) throw new DjenericException(Messages.getString("global.SessionClosed")); 685 if (!isCommitAllowed()) throw new DjenericException(Messages.getString("global.CommitNotAllowed")); 686 687 for (int i = 0; i < getModifiedObjects().size(); i++) 690 { 691 DjObject po = getModifiedObjects().getDjenericObjectAt(i); 692 po.notifyStartTransaction(); 693 } 694 695 700 boolean doneOne; 701 do 702 { 703 doneOne = false; 704 updateDetailOfnewMasterFlags(); 705 706 for (int i = 0; i < getModifiedObjects().size(); i++) 707 { 708 DjObject po = getModifiedObjects().getDjenericObjectAt(i); 709 if (po.isNew() && !po.isDetailOfNewMaster() && !po.isHitDuringCurrentTransaction()) 710 { 711 po.insert(); 712 doneOne = true; 713 po.setHitDuringCurrentTransaction(true); 714 } 715 } 716 } 717 while (doneOne); 718 719 updateDetailFlags(); 721 722 for (int i = 0; i < getModifiedObjects().size(); i++) 723 { 724 DjObject po = getModifiedObjects().getDjenericObjectAt(i); 725 if (!po.isDetail()) po.applyUpdates(); 728 } 729 730 for (int i = 0; i < getModifiedObjects().size(); i++) 731 { 732 DjObject po = getModifiedObjects().getDjenericObjectAt(i); 733 if (!po.isDetail()) po.applyDeletes(); 736 } 737 738 for (int i = 0; i < getModifiedObjects().size(); i++) 744 { 745 DjObject po = getModifiedObjects().getDjenericObjectAt(i); 746 po.applyUpdates(); 747 } 748 for (int i = 0; i < getModifiedObjects().size(); i++) 749 { 750 DjObject po = getModifiedObjects().getDjenericObjectAt(i); 751 po.applyDeletes(); 752 } 753 754 if (shouldTrace(DjPersistenceManager.TRACE_FLOW)) trace("Session post completed"); 755 } 756 757 763 protected void notifyApplySuccesfull() throws DjenericException 764 { 765 for (int i = 0; i < getModifiedObjects().size(); i++) 769 { 770 DjObject po = getModifiedObjects().getDjenericObjectAt(i); 771 if (!po.isMarkedForDelete()) _sessionCache.cache(po); 773 if (!po.isDetail()) po.notifyApplySuccesfull(); 774 } 775 776 780 resetValidValueLists(); 781 782 getModifiedObjects().clear(); 785 if (shouldTrace(DjPersistenceManager.TRACE_FLOW)) trace("Session applied"); 786 } 787 788 795 public DjObject createObject(String extentName) throws DjenericException 796 { 797 if (!isValid()) throw new DjenericException(Messages.getString("global.SessionClosed")); 798 if (shouldTrace(DjPersistenceManager.TRACE_FLOW)) trace("Create new " + extentName); 799 return createObject(getPersistenceManager().getExtent(extentName)); 800 } 801 802 812 protected DjObject getFromSession(long id) throws DjenericException 813 { 814 for (int i = 0; i < getModifiedObjects().size(); i++) 815 { 816 DjObject p = getModifiedObjects().getDjenericObjectAt(i); 817 if (p.getObjectId() == id) 818 { 819 if (shouldTrace(DjPersistenceManager.TRACE_FLOW)) trace("Retrieved " + p.toString() 820 + " from the modified objects list"); 821 return p; 822 } 823 } 824 DjObject result = _sessionCache.lookup(id); 825 if (result != null) 826 { 827 if (shouldTrace(DjPersistenceManager.TRACE_INTERNAL)) trace("Retrieved " + result.toString() + " from the cache"); 828 } 829 else 830 { 831 if (shouldTrace(DjPersistenceManager.TRACE_INTERNAL)) trace("Cache miss for object with id " + id); 832 } 833 return result; 834 } 835 836 DjList getValidMasterObjects(DjObject detail, DjExtent masterExtent, DjRestriction restriction, 837 boolean forceReloadFromDB) throws DjenericException 838 { 839 if (!isValid()) throw new DjenericException(Messages.getString("global.SessionClosed")); 840 841 if (restriction == null) return getObjects(masterExtent); 842 843 DjList results = new DjList(); 844 results.setStoredTypeName(masterExtent); 845 try 846 { 847 long restrictingOid = restriction.evaluate(detail); 848 String restrictingPropertyName = restriction.getTopLevelRestrictedProperty().getName(); 849 850 addNewObjectsFromSession(masterExtent, restrictingPropertyName, restrictingOid, results); 853 addValidMasterObjects(masterExtent, restrictingOid, restrictingPropertyName, forceReloadFromDB, results); 855 } 856 catch (RestrictionFailedException restrictFail) 857 { } 864 return results; 865 } 866 867 protected void notifyModified(DjObject obj, boolean isModified) 868 { 869 try 870 { 871 if (isModified) 872 { 873 addToModifiedList(obj); 874 if (shouldTrace(DjPersistenceManager.TRACE_FLOW)) trace("Modified " + obj.getExtent().getObjectType() + "(id=" 875 + obj.getObjectId() + ") " + obj.toString()); 876 } 877 else removeFromModifiedList(obj); 878 } 879 catch (Exception x) 880 { 881 DjLogger.log(x); 882 } 884 } 885 886 890 public synchronized long getNextTransientObjectId() 891 { 892 return _nextTransientObjectId--; 893 } 894 895 898 public DjObject getObject(DjUid uid) throws DjenericException 899 { 900 DjQueryByExample qbe = createQueryByExample(uid.getExtent()); 901 String [] names = uid.getPropertyNames(); 902 for (int i = 0; i < names.length; i++) 903 { 904 if (uid.isUidProperty(names[i])) qbe.set(names[i], getObject(uid.getUid(names[i]))); 905 else qbe.setString(names[i], uid.getString(names[i])); 906 } 907 DjList lst = getObjects(qbe); 908 if (lst.size() == 0) throw new ObjectNotDefinedException(Messages.getString("DjPersistenceManager.ObjectNotFound", 909 uid.getExtent().getNameSingular(), uid 910 .getDescriptor())); 911 if (lst.size() != 1) 912 { 913 StringBuffer sb = new StringBuffer (100); 914 String [] props = uid.getPropertyNames(); 915 for (int i = 0; i < props.length; i++) 916 { 917 if (i != 0) sb.append(", "); 918 sb.append(props[i]); 919 } 920 System.err.println(uid); 922 for (int i = 0; i < lst.size(); i++) 923 { 924 System.err.println("id=" + lst.getDjenericObjectAt(i).getObjectId() + "; " + lst.getDjenericObjectAt(i)); 925 } 926 throw new CatalogException(Messages.getString("DjPersistenceManager.MultipleHits", uid.getExtent() 927 .getNameSingular(), uid.getDescriptor(), sb.toString())); 928 } 929 return lst.getDjenericObjectAt(0); 930 } 931 932 } | Popular Tags |