1 19 package org.netbeans.mdr.storagemodel; 20 21 import java.util.*; 22 import javax.jmi.reflect.*; 23 import javax.jmi.model.*; 24 import java.io.*; 25 26 import org.netbeans.mdr.handlers.*; 27 import org.netbeans.mdr.persistence.*; 28 import org.netbeans.mdr.util.*; 29 import org.netbeans.mdr.handlers.gen.TagSupport; 30 31 36 public class StorableAssociation extends StorableBaseObject implements Streamable { 37 38 39 private transient Index aIndex; 40 41 private transient Index bIndex; 42 43 private String endA; 44 45 private String endB; 46 47 private org.netbeans.mdr.persistence.MOFID endAId; 48 private org.netbeans.mdr.persistence.MOFID endBId; 49 50 private transient boolean multiValuedA; 51 private transient boolean multiValuedB; 52 53 private int minA, maxA; 54 private int minB, maxB; 55 private transient Class typeA; 56 private transient Class typeB; 57 private int typeANameIndex; 58 private int typeBNameIndex; 59 private boolean orderedA; 60 private boolean orderedB; 61 private boolean aggrA; 62 private boolean aggrB; 63 private boolean indexedA, indexedB; 64 private Class associationSuperclass = null; 65 private final Object superclassMutex = new Object (); 66 67 71 public StorableAssociation() { 72 super(); 73 } 74 75 78 protected void replaceValues(Map table) { 79 objectWillChange(); 80 81 super.replaceValues(table); 82 endAId = (org.netbeans.mdr.persistence.MOFID) table.get(endAId); 83 endBId = (org.netbeans.mdr.persistence.MOFID) table.get(endBId); 84 85 objectChanged(); 86 } 87 88 104 public StorableAssociation(MdrStorage mdrStorage, org.netbeans.mdr.persistence.MOFID immediatePackage, org.netbeans.mdr.persistence.MOFID meta, 105 String endA, org.netbeans.mdr.persistence.MOFID endAId, String endB, org.netbeans.mdr.persistence.MOFID endBId, Class typeA, Class typeB, 106 int minA, int maxA, int minB, int maxB, boolean orderedA, boolean orderedB, 107 boolean uniqueA, boolean uniqueB, boolean aggrA, boolean aggrB, 108 boolean indexedA, boolean indexedB) throws StorageException { 109 110 super(mdrStorage, immediatePackage, meta); 111 112 this.endA = endA; 114 this.endB = endB; 115 this.endAId = endAId; 116 this.endBId = endBId; 117 this.orderedA = orderedA; 118 this.orderedB = orderedB; 119 this.multiValuedA = (maxA != 1); 120 this.multiValuedB = (maxB != 1); 121 this.aggrA = aggrA; 122 this.aggrB = aggrB; 123 this.minA = minA; 124 this.minB = minB; 125 this.maxA = maxA; 126 this.maxB = maxB; 127 this.typeA = typeA; 128 this.typeB = typeB; 129 this.indexedA = indexedA; 130 this.indexedB = indexedB; 131 this.typeANameIndex = mdrStorage.values(this.getMofId()).store(typeA.getName()); 132 this.typeBNameIndex = mdrStorage.values(this.getMofId()).store(typeB.getName()); 133 aIndex = createIndex(multiValuedA, orderedA, uniqueA, 1); 134 bIndex = createIndex(multiValuedB, orderedB, uniqueB, 2); 135 136 getMdrStorage().addObject(this); 137 initFinished = true; 138 } 139 140 public Class getAssociationSuperclass() throws StorageException, ClassNotFoundException { 141 if (associationSuperclass == null) { 142 synchronized (superclassMutex) { 143 if (associationSuperclass == null) { 144 objectWillChange(); 145 associationSuperclass = resolveAssociationSuperclass(); 146 objectChanged(); 147 } 148 } 149 } 150 return associationSuperclass; 151 } 152 153 private Class resolveAssociationSuperclass() throws StorageException, ClassNotFoundException { 154 try { 155 return BaseObjectHandler.resolveImplementation(TagSupport.getImplFullName(getMetaObject(), TagSupport.ASSOCIATION)); 156 } catch (ClassNotFoundException e) { 157 return AssociationHandler.class; 160 } 161 } 162 163 public Class getAssociationCustomImpl() { 164 try { 165 Class sup = getAssociationSuperclass(); 166 return sup == AssociationHandler.class ? null : sup; 167 } catch (Exception e) {} 168 return null; 169 } 170 171 174 public boolean isMultivaluedA () { 175 return multiValuedA; 176 } 177 178 181 public boolean isMultivaluedB () { 182 return multiValuedB; 183 } 184 185 188 public boolean isOrderedA () { 189 return orderedA; 190 } 191 192 195 public boolean isOrderedB () { 196 return orderedB; 197 } 198 199 202 public boolean isAggregateA() { 203 return aggrA; 204 } 205 206 209 public boolean isAggregateB() { 210 return aggrB; 211 } 212 213 216 public boolean isIndexedA() { 217 return indexedA; 218 } 219 220 223 public boolean isIndexedB() { 224 return indexedB; 225 } 226 227 230 public String getEnd1Name() { 231 return this.endA; 232 } 233 234 237 public String getEnd2Name() { 238 return this.endB; 239 } 240 241 public org.netbeans.mdr.persistence.MOFID getEnd1Id () { 242 return this.endAId; 243 } 244 245 public org.netbeans.mdr.persistence.MOFID getEnd2Id () { 246 return this.endBId; 247 } 248 249 255 public boolean linkExists (org.netbeans.mdr.persistence.MOFID a, org.netbeans.mdr.persistence.MOFID b) throws StorageException { 256 if (isMultivaluedB()) { 257 return ((MultivaluedIndex) bIndex).getItems(a).contains(b); 258 } else { 259 return b.equals(((SinglevaluedIndex) bIndex).getIfExists(a)); 260 } 261 } 262 263 270 public Collection getAllLinks() throws StorageException { 271 return new LinkSetCollection(); 272 } 273 274 280 public Object queryObjects(String endName, org.netbeans.mdr.persistence.MOFID obj) throws StorageException { 281 boolean isEndA = endName.equals(endB); 283 boolean multi = isEndA ? multiValuedA : multiValuedB; 284 boolean order = isEndA ? orderedA : orderedB; 285 Index index = isEndA ? aIndex : bIndex; 286 Index secondIndex = isEndA ? bIndex : aIndex; 287 Class type = isEndA ? typeA : typeB; 288 int max = isEndA ? maxA : maxB; 289 org.netbeans.mdr.persistence.MOFID endId, otherEndId; 290 boolean isIndexed, isOtherIndexed; 291 if (isEndA) { 292 endId = endAId; 293 otherEndId = endBId; 294 isIndexed = indexedA; 295 isOtherIndexed = indexedB; 296 } else { 297 endId = endBId; 298 otherEndId = endAId; 299 isIndexed = indexedB; 300 isOtherIndexed = indexedA; 301 } 302 boolean aggr = isEndA ? aggrA : aggrB; 303 boolean otherAggr = isEndA ? aggrB : aggrA; 304 305 Object result; 306 if (obj == null) throw new NullPointerException (); 307 308 if (multi) { 309 if (order) { 310 result = new AssocEndIndexUList(this, endId, otherEndId, (MultivaluedOrderedIndex) index, obj, secondIndex, type, max, true, aggr, otherAggr, isIndexed, isOtherIndexed); 311 } else { 312 result = new AssocEndIndexSet(this, endId, otherEndId, (MultivaluedIndex) index, obj, secondIndex, type, max, true, aggr, otherAggr, isIndexed, isOtherIndexed); 313 } 314 } else { 315 result = getMdrStorage().getObjectFromIndexIfExists((SinglevaluedIndex) index, obj); 316 } 317 return result; 318 } 319 320 public void verify(Collection violations) throws StorageException { 321 try { 322 if (getAssociationSuperclass() == AssociationHandler.class) { 323 for (Iterator it = aIndex.keySet().iterator(); it.hasNext();) { 324 verifyEnd(violations, endB, (org.netbeans.mdr.persistence.MOFID) it.next()); 325 } 326 for (Iterator it = bIndex.keySet().iterator(); it.hasNext();) { 327 verifyEnd(violations, endA, (org.netbeans.mdr.persistence.MOFID) it.next()); 328 } 329 } 330 } catch (ClassNotFoundException e) { 331 throw (DebugException) Logger.getDefault().annotate(new DebugException(), e); 332 } 333 } 334 335 public void verifyEnd(Collection violations, String end, org.netbeans.mdr.persistence.MOFID object) throws StorageException { 336 try { 337 if (getAssociationSuperclass() == AssociationHandler.class) { 338 int min = end.equals(endB) ? minA : minB; 339 org.netbeans.mdr.persistence.MOFID endId = end.equals(endB) ? endAId : endBId; 340 Object result = queryObjects(end, object); 341 if ((result == null && min > 0) || 342 (result instanceof Collection && ((Collection) result).size() < min)) { 343 violations.add(new WrongSizeException((RefObject) getMdrStorage().getRepository().getHandler(getMdrStorage().getObject(endId)), 344 "Not enough objects linked to " + object + " at end '" + end + "'.")); 345 } 346 } 347 } catch (ClassNotFoundException e) { 348 throw (DebugException) Logger.getDefault().annotate(new DebugException(), e); 349 } 350 } 351 352 public void checkType(Object endA, Object endB) { 353 try { 354 if (endA != null && !typeA.isInstance(endA)) { 355 throw new TypeMismatchException(typeB, endB, 356 (RefObject) getMdrStorage().getRepository().getHandler(getMdrStorage().getObject(endBId))); 357 } else if (endB != null && !typeB.isInstance(endB)) { 358 throw new TypeMismatchException(typeB, endB, 359 (RefObject) getMdrStorage().getRepository().getHandler(getMdrStorage().getObject(endBId))); 360 } 361 } catch (StorageException e) { 362 throw (DebugException) Logger.getDefault().annotate(new DebugException(), e); 363 } 364 throw new DebugException(); 365 } 366 367 372 public boolean addLink (org.netbeans.mdr.persistence.MOFID a, org.netbeans.mdr.persistence.MOFID b) throws StorageException { 373 if (multiValuedA) { 374 return ((Collection) queryObjects(endB, b)).add(a); 375 } else if (multiValuedB) { 376 return ((Collection) queryObjects(endA, a)).add(b); 377 } else { 378 try { 379 StorableObject oA = null, oB = null; 380 oA = (StorableObject) getMdrStorage().getObject(a); 381 oB = (StorableObject) getMdrStorage().getObject(b); 382 if (indexedA) { 383 oB.removeFromIndex (endAId); 384 } 385 if (indexedB) { 386 oA.removeFromIndex (endBId); 387 } 388 if (aggrA) { 390 oB.setComposite(oA, a, endAId); 391 } else if (aggrB) { 392 oA.setComposite(oB, b, endBId); 393 } 394 aIndex.add(b, a); 395 bIndex.add(a, b); 396 if (indexedA) { 397 oB.addToIndex (endAId); 398 } 399 if (indexedB) { 400 oA.addToIndex (endBId); 401 } 402 403 return true; 404 } catch (StorageBadRequestException e) { 405 return false; 407 } 408 } 409 } 410 411 416 public boolean removeLink (org.netbeans.mdr.persistence.MOFID a, org.netbeans.mdr.persistence.MOFID b) throws StorageException { 417 try { 418 StorableObject oA = null, oB = null; 419 oA = (StorableObject) getMdrStorage().getObject(a); 420 oB = (StorableObject) getMdrStorage().getObject(b); 421 if (indexedA) { 422 oB.removeFromIndex (endAId); 423 } 424 if (indexedB) { 425 oA.removeFromIndex (endBId); 426 } 427 if (aggrA) { 429 oB.clearComposite(); 430 } else if (aggrB) { 431 oA.clearComposite(); 432 } 433 removeLinkEnd(b, a, aIndex, multiValuedA); 434 removeLinkEnd(a, b, bIndex, multiValuedB); 435 if (indexedA) { 436 oB.addToIndex (endAId); 437 } 438 if (indexedB) { 439 oA.addToIndex (endBId); 440 } 441 return true; 442 } catch (StorageBadRequestException e) { 443 return false; 444 } 445 } 446 447 protected Index getIndex(String end) throws StorageException { 448 if (end.equals(endA)) { 449 return aIndex; 450 } else if (end.equals(endB)) { 451 return bIndex; 452 } else { 453 return null; 454 } 455 } 456 457 459 protected Index findIndex(int end) throws StorageException { 460 return getMdrStorage().getIndex(getOutermostPackageId(), getMofId(), end); 461 } 462 463 471 private void removeLinkEnd (org.netbeans.mdr.persistence.MOFID a, org.netbeans.mdr.persistence.MOFID b, Index index, boolean multi) throws StorageException { 472 if (multi) { 473 ((MultivaluedIndex) index).remove(a, b); 474 } else { 475 ((SinglevaluedIndex) index).remove(a); 476 } 477 } 478 479 487 protected Index createIndex (boolean multi, boolean ordered, boolean unique, int end) throws StorageException { 488 if (multi) { 489 if (ordered) { 490 return getMdrStorage().createMultivaluedOrderedIndex(getOutermostPackageId(), getMofId(), end, Storage.EntryType.MOFID, Storage.EntryType.MOFID, unique); 491 } else { 492 return getMdrStorage().createMultivaluedIndex(getOutermostPackageId(), getMofId(), end, Storage.EntryType.MOFID, Storage.EntryType.MOFID, unique); 493 } 494 } else { 495 return getMdrStorage().createSinglevaluedIndex (getOutermostPackageId(), getMofId(), end, Storage.EntryType.MOFID, Storage.EntryType.MOFID); 496 } 497 } 498 499 protected void deleteIndex (org.netbeans.mdr.persistence.MOFID opkgId, org.netbeans.mdr.persistence.MOFID mofId, int index) throws StorageException { 500 getMdrStorage().dropIndex(opkgId, mofId, index); 501 } 502 503 protected void deleteRecursive() throws StorageException { 504 deleteIndex (getOutermostPackageId(), getMofId(), 1); 505 deleteIndex (getOutermostPackageId(), getMofId(), 2); 506 super.deleteRecursive(); 507 } 508 509 513 public void write(java.io.OutputStream outputStream) { 514 516 super.write (outputStream); 517 518 try { 519 IOUtils.write (outputStream, meta, this); 520 IOUtils.write (outputStream, immediatePackage, this); 521 IOUtils.writeString(outputStream, endA); 522 IOUtils.writeString(outputStream, endB); 523 IOUtils.write (outputStream, endAId, this); 524 IOUtils.write (outputStream, endBId, this); 525 IOUtils.writeInt(outputStream, minA); 526 IOUtils.writeInt(outputStream, maxA); 527 IOUtils.writeInt(outputStream, minB); 528 IOUtils.writeInt(outputStream, maxB); 529 IOUtils.writeBoolean(outputStream, aggrA); 530 IOUtils.writeBoolean(outputStream, aggrB); 531 IOUtils.writeBoolean(outputStream, orderedA); 532 IOUtils.writeBoolean(outputStream, orderedB); 533 IOUtils.writeInt(outputStream, typeANameIndex); 534 IOUtils.writeInt(outputStream, typeBNameIndex); 535 IOUtils.writeBoolean(outputStream, indexedA); 536 IOUtils.writeBoolean(outputStream, indexedB); 537 } catch (java.io.IOException e) { 538 Logger.getDefault().notify(Logger.INFORMATIONAL, e); 539 } 540 } 541 542 546 public void read(java.io.InputStream inputStream) { 547 super.read (inputStream); 548 try { 549 meta = (org.netbeans.mdr.persistence.MOFID) IOUtils.read (inputStream,this); 550 immediatePackage = (org.netbeans.mdr.persistence.MOFID) IOUtils.read (inputStream, this); 551 552 endA = IOUtils.readString(inputStream); 553 endB = IOUtils.readString(inputStream); 554 endAId = (org.netbeans.mdr.persistence.MOFID) IOUtils.read (inputStream, this); 555 endBId = (org.netbeans.mdr.persistence.MOFID) IOUtils.read (inputStream, this); 556 minA = IOUtils.readInt(inputStream); 557 maxA = IOUtils.readInt(inputStream); 558 minB = IOUtils.readInt(inputStream); 559 maxB = IOUtils.readInt(inputStream); 560 multiValuedA = (maxA != 1); 561 multiValuedB = (maxB != 1); 562 aggrA = IOUtils.readBoolean(inputStream); 563 aggrB = IOUtils.readBoolean(inputStream); 564 orderedA = IOUtils.readBoolean(inputStream); 565 orderedB = IOUtils.readBoolean(inputStream); 566 typeANameIndex = IOUtils.readInt(inputStream); 567 typeBNameIndex = IOUtils.readInt(inputStream); 568 aIndex = findIndex(1); 569 bIndex = findIndex(2); 570 typeA = BaseObjectHandler.resolveInterface((String ) getMdrStorage().values(this.getMofId()).resolve(typeANameIndex)); 571 typeB = BaseObjectHandler.resolveInterface((String ) getMdrStorage().values(this.getMofId()).resolve(typeBNameIndex)); 572 indexedA = IOUtils.readBoolean(inputStream); 573 indexedB = IOUtils.readBoolean(inputStream); 574 } catch (java.io.IOException e) { 575 throw (DebugException) Logger.getDefault().annotate(new DebugException(), e); 576 } catch (StorageException ex) { 577 throw (DebugException) Logger.getDefault().annotate(new DebugException(), ex); 578 } catch (ClassNotFoundException e) { 579 throw (DebugException) Logger.getDefault().annotate(new DebugException(), e); 580 } 581 } 582 583 584 585 586 587 protected class LinkSetCollection extends AbstractCollection { 588 589 public Iterator iterator() { 590 return new LinkSetIterator(); 591 } 592 593 public int size() { 594 try { 595 int size = 0; 596 for (Iterator as = bIndex.keySet().iterator(); as.hasNext();) { 597 MOFID aID = (MOFID) as.next(); 598 if ( isMultivaluedB() ) { 600 size += getMdrStorage().getObjectsFromIndex((MultivaluedIndex) bIndex, aID).size(); 601 } else { 602 size++; 603 } 604 } 605 return size; 606 } catch (StorageException se) { 607 throw (DebugException) Logger.getDefault().annotate(new DebugException(), se); 608 } 609 } 610 } 611 612 613 614 615 616 protected class LinkSetIterator implements Iterator { 617 618 boolean initialized = false; 619 620 625 Iterator as = null; 626 627 631 org.netbeans.mdr.persistence.MOFID aID = null; 632 633 637 StorableObject a = null; 638 639 644 Iterator bs = null; 645 646 650 StorableObject b = null; 651 652 private void initCheck() { 653 if ( ! initialized ) { 654 initialized = true; 655 try { 656 as = bIndex.keySet().iterator(); 657 } catch ( StorageException se ) { 658 as = null; 660 } 661 fetchNext(); 662 } 663 } 664 665 private void fetchNext() { 666 if ( as == null ) { 667 return; 668 } 669 b = null; 670 if ( bs != null ) { 672 if ( bs.hasNext() ) { 673 b = (StorableObject) bs.next(); 674 return; 675 } 676 } 677 678 try { 679 while ( as.hasNext() ) { 681 aID = (org.netbeans.mdr.persistence.MOFID) as.next(); 682 a = null; 683 if ( isMultivaluedB() ) { 685 bs = getMdrStorage().getObjectsFromIndex((MultivaluedIndex) bIndex, aID).iterator(); 686 if ( bs.hasNext() ) { 687 b = (StorableObject) bs.next(); 688 } 689 } else { 690 b = (StorableObject) getMdrStorage().getObjectFromIndexIfExists((SinglevaluedIndex) bIndex, aID); 691 } 692 if ( b != null ) { 694 return; 695 } 696 } 697 } catch (StorageException se) { 698 as = null; 700 b = null; 701 } 702 703 return; 705 } 706 707 public boolean hasNext() { 708 initCheck(); 709 return b != null; 710 } 711 712 public Object next() { 713 initCheck(); 714 if ( b == null ) { 715 throw new NoSuchElementException(); 716 } 717 if ( a == null ) { 718 try { 719 a = (StorableObject) getMdrStorage().getObject(aID); 720 } catch (StorageException se) { 721 throw (DebugException) Logger.getDefault().annotate(new DebugException(), se); 723 } 724 } 725 AssociationLink link = new AssociationLink(a,b); 726 fetchNext(); 727 return link; 728 } 729 730 733 public void remove() { 734 throw new UnsupportedOperationException (); 735 } 736 737 } 738 } 739 | Popular Tags |