1 30 package com.genimen.djeneric.repository; 31 32 import java.util.ArrayList ; 33 34 import com.genimen.djeneric.language.Messages; 35 import com.genimen.djeneric.repository.exceptions.CanNotDeleteException; 36 import com.genimen.djeneric.repository.exceptions.DjenericException; 37 import com.genimen.djeneric.repository.exceptions.ObjectNotDefinedException; 38 import com.genimen.djeneric.repository.exceptions.PropertyFormatException; 39 40 49 public class DjAssociation 50 { 51 DjObject _master; 52 DjExtent _detailExtent; 53 DjRelation _rel; 54 ArrayList _synchronizationListeners = null; 55 56 DjList _loadedDetails = null; 58 boolean _specializationOfActualDetailExtent = false; 59 60 DjSession _session; 61 62 72 protected DjAssociation(DjSession session, DjObject master, DjRelation rel, DjExtent specificDetailExtent) 73 { 74 _session = session; 75 _master = master; 76 _detailExtent = specificDetailExtent; 77 _rel = rel; 78 } 79 80 public boolean isSpecialized() 81 { 82 return _rel.getDetailExtent() != _detailExtent; 83 } 84 85 92 protected DjQueryByExample createNewQbe() throws DjenericException 93 { 94 return _session.createQueryByExample(_detailExtent); 95 } 96 97 103 public DjRestriction getRestriction() throws DjenericException 104 { 105 return getRelation().getRestriction(); 106 } 107 108 114 public String getName() 115 { 116 return _rel.getName(); 117 } 118 119 125 protected DjList getLoadedDetailArrayList() 126 { 127 return _loadedDetails; 128 } 129 130 135 protected DjSession getSession() 136 { 137 return _session; 138 } 139 140 145 public DjObject getMaster() 146 { 147 return _master; 148 } 149 150 155 public DjExtent getMasterExtent() 156 { 157 return _master.getExtent(); 158 } 159 160 165 public DjExtent getDetailExtent() 166 { 167 return _detailExtent; 168 } 169 170 175 public DjRelation getRelation() 176 { 177 return _rel; 178 } 179 180 185 public String toString() 186 { 187 String result; 188 if (_rel.isDetailsContained()) result = Messages.getString("DjAssociation.ByValue", getName()); 189 else result = Messages.getString("DjAssociation.ByReference", getName()); 190 191 return result; 192 } 193 194 199 public String getDescription() 200 { 201 return _rel.getDescription(); 202 } 203 204 210 public DjObject createNew() throws DjenericException 211 { 212 DjObject po = _session.createObject(_detailExtent); 213 214 po.set(getRelation().getDetailProperty().getName(), getMaster()); 216 217 222 return po; 223 } 224 225 230 public boolean isDetailsLoaded() 231 { 232 return (_loadedDetails != null); 233 } 234 235 241 public boolean objectsExist() throws DjenericException 242 { 243 if (isDetailsLoaded() && getObjects().size() > 0) return true; 244 return detailsExist(); 245 } 246 247 254 public DjList getNewObjectsFromSession() throws DjenericException 255 { 256 DjList lst = new DjList(); 257 lst.setStoredTypeName(_detailExtent); 258 getSession().addNewDetailsFromSession(getMaster(), getRelation(), _detailExtent, lst); 259 return lst; 260 } 261 262 268 public DjList getObjects() throws DjenericException 269 { 270 return getObjects(false); 271 } 272 273 public void load() throws DjenericException 274 { 275 getObjects(false); 276 } 277 278 288 public DjList getObjects(boolean reloadFromDb) throws DjenericException 289 { 290 if (_loadedDetails == null || reloadFromDb) 291 { 292 loadDetails(null, reloadFromDb); 293 } 294 else _loadedDetails.purgeDeleted(); 295 296 return _loadedDetails; 297 } 298 299 313 public DjList getObjects(DjQueryByExample qbe, boolean reloadFromDb) throws DjenericException 314 { 315 loadDetails(qbe, reloadFromDb); 316 return _loadedDetails; 317 } 318 319 326 protected boolean isDetailsContained() 327 { 328 return _rel.isDetailsContained(); 329 } 330 331 337 public void synchronizeWithSession() throws DjenericException 338 { 339 boolean wasLoaded = isDetailsLoaded(); 341 342 if (!wasLoaded) _loadedDetails = new DjList(); 343 _loadedDetails.setStoredTypeName(getDetailExtent()); 344 345 boolean needsSynch = false; 346 DjList added = null; 347 DjList removed = null; 348 349 DjList lst = new DjList(); 351 lst.setStoredTypeName(_detailExtent); 352 getSession().addDetailsFromSession(getMaster(), getRelation(), _detailExtent, lst); 353 354 for (int i = 0; i < lst.size(); i++) 355 { 356 DjObject obj = (DjObject) lst.get(i); 357 358 if (!_loadedDetails.contains(obj)) 359 { 360 _loadedDetails.add(lst.get(i)); 361 needsSynch = true; 362 if (added == null) 363 { 364 added = new DjList(); 365 added.setStoredTypeName(_detailExtent); 366 } 367 368 added.add(lst.get(i)); 369 } 370 } 371 372 DjQueryByExample qbe = createNewQbe(); 376 DjExtent detailExtent = getDetailExtent(); 377 int detailPropIdx = detailExtent.getPropertyIndex(getRelation().getDetailProperty().getName()); 378 long masterObjectId = getMaster().getObjectId(); 379 qbe.setLong(detailPropIdx, masterObjectId); 380 int i = 0; 381 while (i < _loadedDetails.size()) 382 { 383 DjObject obj = _loadedDetails.getDjenericObjectAt(i); 384 385 if (!qbe.match(obj) || obj.isMarkedForDelete()) 386 { 387 if (removed == null) 388 { 389 removed = new DjList(); 390 removed.setStoredTypeName(_detailExtent); 391 } 392 removed.add(_loadedDetails.getDjenericObjectAt(i)); 393 _loadedDetails.remove(i); 394 needsSynch = true; 395 } 396 else i++; 397 } 398 399 if (!wasLoaded && !needsSynch) _loadedDetails = null; 402 else if (needsSynch) fireNeedsSynch(added, removed); 403 } 404 405 protected void fireNeedsSynch(DjList added, DjList removed) 406 { 407 if (_synchronizationListeners == null) return; 408 409 if (added == null) 410 { 411 added = new DjList(); 412 added.setStoredTypeName(_detailExtent); 413 } 414 415 if (removed == null) 416 { 417 removed = new DjList(); 418 removed.setStoredTypeName(_detailExtent); 419 } 420 421 for (int i = 0; i < _synchronizationListeners.size(); i++) 422 { 423 DjSynchronizationListener lsnr = (DjSynchronizationListener) _synchronizationListeners.get(i); 424 lsnr.synchNeeded(this, added, removed); 425 } 426 } 427 428 public void addSynchronizationListener(DjSynchronizationListener lsnr) 429 { 430 if (_synchronizationListeners == null) _synchronizationListeners = new ArrayList (); 431 432 if (!_synchronizationListeners.contains(lsnr)) _synchronizationListeners.add(lsnr); 433 } 434 435 public void removeSynchronizationListener(DjSynchronizationListener lsnr) 436 { 437 if (_synchronizationListeners == null) return; 438 _synchronizationListeners.remove(lsnr); 439 } 440 441 454 protected void loadDetails(DjQueryByExample qbe, boolean reloadFromDb) throws DjenericException 455 { 456 if (qbe == null) qbe = createNewQbe(); 457 qbe.setLong(getDetailPropertyName(), getMaster().getObjectId()); 458 _loadedDetails = getSession().getObjects(qbe, reloadFromDb); 459 _loadedDetails.setStoredTypeName(getDetailExtent()); 460 } 461 462 473 public DjCursor getObjectsCursor(boolean forceReloadFromDB) throws DjenericException 474 { 475 return getObjectsCursor(createNewQbe(), forceReloadFromDB); 476 } 477 478 492 public DjCursor getObjectsCursor(DjQueryByExample qbe, boolean forceReloadFromDB) throws DjenericException 493 { 494 qbe.setLong(getDetailPropertyName(), getMaster().getObjectId()); 495 return getSession().getObjectsCursor(qbe, forceReloadFromDB); 496 } 497 498 public String getDetailPropertyName() 499 { 500 return getRelation().getDetailProperty().getName(); 501 } 502 503 517 public DjCursor getObjectsCursor(DjOql oql, boolean forceReloadFromDB) throws DjenericException 518 { 519 String masterPropertyName = "_master" + getDetailPropertyName(); 520 521 oql.addBaseRestriction(getDetailPropertyName() + " == :" + masterPropertyName); 522 oql.setParameter(masterPropertyName, getMaster().getObjectId()); 523 return getSession().getObjectsCursor(oql, forceReloadFromDB); 524 } 525 526 534 protected boolean detailsExist() throws DjenericException 535 { 536 DjQueryByExample qbe = createNewQbe(); 537 qbe.setLong(getRelation().getDetailProperty().getName(), getMaster().getObjectId()); 538 DjCursor cursor = null; 539 try 540 { 541 cursor = getSession().getObjectsCursor(qbe); 542 DjObject obj = null; 543 while ((obj = cursor.getNext()) != null) 544 { 545 if (!obj.isMarkedForDelete()) return true; 546 } 547 return false; 548 } 549 finally 550 { 551 if (cursor != null) cursor.close(); 552 } 553 } 554 555 public boolean isOneToOne() 556 { 557 return getRelation().isOneToOne(); 558 } 559 560 public boolean isOneToMany() 561 { 562 return getRelation().isOneToMany(); 563 } 564 565 public void addAll(DjList list) throws DjenericException 566 { 567 for (int i = 0; i < list.size(); i++) 568 { 569 add(list.getDjenericObjectAt(i)); 570 } 571 } 572 573 public void add(DjObject detail) throws DjenericException 574 { 575 if (!isDetailsLoaded()) load(); 576 577 if (!getObjects().contains(detail)) 578 { 579 if (isOneToOne()) 580 { 581 removeCurrentDetails(); 582 } 583 getObjects().add(detail); 584 } 585 detail.set(getDetailPropertyName(), getMaster()); 586 } 587 588 public void remove(DjObject detail) throws DjenericException 589 { 590 if (!isDetailsLoaded()) return; 591 getObjects().remove(detail); 592 } 593 594 private void removeCurrentDetails() throws CanNotDeleteException, DjenericException 595 { 596 for (int i = 0; i < getObjects().size(); i++) 597 { 598 unlinkDetail(i); 599 } 600 getObjects().clear(); 601 } 602 603 private void unlinkDetail(int i) throws DjenericException, CanNotDeleteException, ObjectNotDefinedException, 604 PropertyFormatException 605 { 606 if (isDetailsContained()) getObjects().getDjenericObjectAt(i).markForDelete(); 607 else getObjects().getDjenericObjectAt(i).set(getDetailPropertyName(), null); 608 } 609 610 public void replaceDetail(int indexValue, DjObject detail) throws DjenericException 611 { 612 if (!getObjects().contains(detail)) 613 { 614 unlinkDetail(indexValue); 615 getObjects().set(indexValue, detail); 616 } 617 } 618 619 public boolean isSpecializationOfActualDetailExtent() 620 { 621 return _specializationOfActualDetailExtent; 622 } 623 624 public void setSpecializationOfActualDetailExtent(boolean specializationOfActualDetailExtent) 625 { 626 _specializationOfActualDetailExtent = specializationOfActualDetailExtent; 627 } 628 629 public void markAllDeleted() throws CanNotDeleteException, DjenericException 630 { 631 getObjects().markAllDeleted(); 632 } 633 634 public void markAllDeletedExcluding(ArrayList lst) throws CanNotDeleteException, DjenericException 635 { 636 getObjects().markAllDeletedExcluding(lst); 637 } 638 639 } | Popular Tags |