1 19 20 package org.netbeans.modules.java.bridge; 21 22 import java.lang.ref.WeakReference ; 23 import java.util.*; 24 import javax.jmi.reflect.InvalidObjectException; 25 import javax.jmi.reflect.RefObject; 26 import org.netbeans.api.mdr.events.AttributeEvent; 27 import org.netbeans.api.mdr.events.MDRChangeEvent; 28 import org.netbeans.api.mdr.events.MDRChangeSource; 29 import org.netbeans.jmi.javamodel.*; 30 import org.netbeans.modules.javacore.JMManager; 31 import org.netbeans.modules.javacore.internalapi.JavaMetamodel; 32 import org.openide.ErrorManager; 33 import org.openide.src.Element; 34 import org.openide.src.*; 35 import org.openide.src.Type; 36 37 abstract class ObjectsCollection { 38 39 static int POS_VAL_NONE = -1; 40 static int POS_VAL_FIELD = 0; 41 static int POS_VAL_INITIALIZER = 1; 42 static int POS_VAL_CONSTRUCTOR = 2; 43 static int POS_VAL_METHOD = 3; 44 static int POS_VAL_CLASS = 4; 45 46 static final Type[] NO_TYPES = new Type[0]; 47 48 private WeakHashMap cache = new WeakHashMap (); 49 50 protected FeaturesCollection members; 51 52 54 public ObjectsCollection(FeaturesCollection members) { 55 this.members = members; 56 } 57 58 public abstract RefObject createFeature (RefObject parent, Element elem); 59 60 public abstract Element createElement (RefObject javaElement); 61 62 public abstract Element[] getEmptyArray (); 63 64 public abstract String getPropertyName (); 65 66 public abstract boolean isOfType (RefObject feature); 67 68 protected Element cachedElement (RefObject refObject) { Element elem; 70 WeakReference ref = (WeakReference ) cache.get (refObject); 71 72 if (ref != null) { 73 elem = (Element) ref.get(); 74 if (elem != null) 75 return elem; 76 } 77 members.repository.beginTrans (false); 78 try { 79 members.parentImpl.setClassPath(); 80 elem = createElement (refObject); 81 cache.put (refObject, new WeakReference (elem)); 82 return elem; 83 } finally { 84 members.repository.endTrans (false); 85 } 86 } 87 88 public List getFeatures () { 89 return members.javaClass.getFeatures (); 90 } 91 92 public boolean isValid() { 93 return members.javaClass.isValid(); 94 } 95 96 public abstract boolean matches (Element elem, RefObject f); 97 98 public int getPositionalValue () { 99 return POS_VAL_NONE; 100 } 101 102 public boolean isClassMember () { return true; 104 } 105 106 public Element [] getElements () { 107 ArrayList result = new ArrayList (); 108 members.repository.beginTrans (false); 109 try { 110 if (isValid()) { 111 members.parentImpl.setClassPath(); 112 List features = getFeatures (); 113 if (features != null) { 114 for (Iterator iter = features.iterator (); iter.hasNext ();) { 115 RefObject feature = (RefObject) iter.next (); 116 if (isOfType (feature)) { 117 result.add (cachedElement (feature)); 118 } 119 } 120 } 121 return (Element []) result.toArray (getEmptyArray ()); 122 } else { 123 return getEmptyArray (); 124 } 125 } finally { 126 members.repository.endTrans (false); 127 } 128 } 129 130 private Element [] getMembers () { 131 List features = getFeatures (); 132 int size = features.size (); 133 Element [] result = new Element [size]; 134 Iterator iter = features.iterator (); 135 for (int x = 0; x < size; x++) { 136 RefObject feature = (RefObject) iter.next (); 137 result [x] = cachedMember (feature); 138 } 139 return result; 140 } 141 142 private Element cachedMember (RefObject f) { 143 if (f instanceof JavaClass) { 144 return ((ClassElementImpl) members.parentImpl).innerClasses.cachedElement (f); 145 } else if (f instanceof Method) { 146 return ((ClassElementImpl) members.parentImpl).methods.cachedElement (f); 147 } else if (f instanceof Constructor) { 148 return ((ClassElementImpl) members.parentImpl).constructors.cachedElement (f); 149 } else if (f instanceof Field) { 150 return ((ClassElementImpl) members.parentImpl).fields.cachedElement (f); 151 } else if (f instanceof Initializer) { 152 return ((ClassElementImpl) members.parentImpl).initializers.cachedElement (f); 153 } 154 throw new RuntimeException (); 155 } 156 157 public void changeMembers(Element[] items, int operation) throws SourceException { 158 159 for (int x = 0; x < items.length; x++) 160 if (items [x] == null) 161 throw new NullPointerException ("null element in " + items.getClass ().getName ()); 163 switch (operation) { 164 case ClassElementImpl.ADD: 165 addMembers(items); 166 break; 167 case ClassElementImpl.REMOVE: 168 removeMembers(items); 169 break; 170 case ClassElementImpl.SET: 171 setMembers(items); 172 break; 173 default: 174 throw new RuntimeException ("Unknown/unsupported operation: " + operation); } 176 } 177 178 protected void addMembers (Element[] items) throws SourceException { 179 int i; 180 if (items.length == 0) 181 return; 182 183 boolean veto = isClassMember () && ( 184 members.parentImpl.hasVetoableListeners (getPropertyName ()) || 185 members.parentImpl.hasVetoableListeners (ElementProperties.PROP_MEMBERS)); 186 Element [] oldElems = null; 187 Element [] oldMembers = null; 188 189 members.repository.beginTrans (true); 190 boolean failed = true; 191 try { 192 if (isValid()) { 193 members.parentImpl.setClassPath(); 194 195 if (veto) { 196 oldElems = getElements (); 197 oldMembers = getMembers (); 198 } 199 200 int index = findAddPosition (getPositionalValue ()); 201 ListIterator listIter = getFeatures ().listIterator (index); 202 for (i = 0; i < items.length; i++) { 203 Object feature = createFeature (members.javaClass, items[i]); 204 listIter.add (feature); 205 } 206 207 if (veto) { 208 MultiPropertyChangeEvent evt; 209 int [] indexes = new int [items.length]; 210 List added = Arrays.asList (items); 211 Element [] newMembers = getMembers (); 213 for (int x = 0; x < items.length; x++) { 214 indexes [x] = x + index; 215 } 216 evt = new MultiPropertyChangeEvent( 217 members.parentImpl.getElement (), ElementProperties.PROP_MEMBERS, oldMembers, newMembers); 218 evt.makeInsertion (added, indexes); 219 members.parentImpl.checkVetoablePropertyChange (evt); 220 Element [] newElems = getElements (); 222 indexes = new int [items.length]; 223 for (int x = 0; x < items.length; x++) { 224 indexes [x] = x + oldElems.length; 225 } 226 evt = new MultiPropertyChangeEvent( 227 members.parentImpl.getElement (), getPropertyName(), oldElems, newElems); 228 evt.makeInsertion (added, indexes); 229 members.parentImpl.checkVetoablePropertyChange (evt); 230 } 231 232 failed = false; 233 } else { 234 failed = false; 235 members.parentImpl.throwIsInvalid (); 236 } 237 } catch (InvalidObjectException e) { 238 members.parentImpl.throwIsInvalid (); 239 } finally { 240 members.repository.endTrans (failed); 241 } 242 } 243 244 protected void removeMembers (Element[] items) throws SourceException { 245 if ((items == null) || (items.length == 0)) 246 return; 247 248 boolean veto = isClassMember () && ( 249 members.parentImpl.hasVetoableListeners (getPropertyName ()) || 250 members.parentImpl.hasVetoableListeners (ElementProperties.PROP_MEMBERS)); 251 Element [] oldElems = null; 252 Element [] oldMembers = null; 253 int elemsCounter, membersCounter, removedCounter; 254 int [] elemsIndexes = null; 255 int [] membersIndexes = null; 256 257 boolean failed = true; 258 members.repository.beginTrans (true); 259 try { 260 if (isValid()) { 261 members.parentImpl.setClassPath(); 262 if (veto) { 263 oldElems = getElements (); 264 oldMembers = getMembers (); 265 elemsIndexes = new int [items.length]; 266 membersIndexes = new int [items.length]; 267 } 268 269 String name; 270 List list; 271 List features = getFeatures (); 272 HashMap map = new HashMap (); 273 for (int x = 0; x < items.length; x++) { 274 if (items [x] instanceof MemberElement) { 275 name = ((MemberElement) items [x]).getName ().getName (); 276 } else if (items [x] instanceof InitializerElement) { 277 name = "initializer"; } else { name = ((ImportElement) items[x]).getImport ().getIdentifier ().getFullName (); 280 } 281 282 list = (List) map.get (name); 283 if (list == null) { 284 list = new LinkedList (); 285 map.put (name, list); 286 } 287 list.add (items [x]); 288 } 289 ListIterator iter = features.listIterator (); 290 membersCounter = elemsCounter = removedCounter = 0; 291 while (iter.hasNext ()) { 292 RefObject f = (RefObject) iter.next (); 293 if (isOfType (f)) { 294 if (f instanceof Constructor) { 295 name = ((JavaClass) ((Constructor) f).getDeclaringClass()).getSimpleName (); 296 } else if (f instanceof Initializer) 297 name = "initializer"; else if (f instanceof org.netbeans.jmi.javamodel.Import) { 299 name = ((org.netbeans.jmi.javamodel.Import) f).getName (); 300 if (name.endsWith (".*")) { name = name.substring (0, name.length() - 2); 302 } 303 } else if (f instanceof JavaClass) { 304 name = ((JavaClass) f).getSimpleName(); 305 } else { 306 name = ((Feature) f).getName (); 307 } 308 list = (List) map.get (name); 309 if (list != null) { 310 Iterator iter2 = list.listIterator (); 311 while (iter2.hasNext ()) { 312 Element elem = (Element) iter2.next (); 313 if (matches (elem, f)) { 314 iter2.remove (); 315 iter.remove(); 316 f.refDelete (); 317 if (list.size () == 0) { 318 map.remove (name); 319 } 320 if (veto) { 321 membersIndexes [removedCounter] = membersCounter; 322 elemsIndexes [removedCounter] = elemsCounter; 323 } 324 removedCounter ++; 325 break; 326 } } } elemsCounter ++; 330 } membersCounter ++; 332 } if (map.size () > 0) { 334 throw new SourceException ("An element to be removed not found."); } 336 337 if (veto) { 338 MultiPropertyChangeEvent evt; 339 List removed = Arrays.asList (items); 340 Element [] newMembers = getMembers (); 342 evt = new MultiPropertyChangeEvent( 343 members.parentImpl.getElement (), ElementProperties.PROP_MEMBERS, oldMembers, newMembers); 344 evt.makeRemoval (removed, membersIndexes); 345 members.parentImpl.checkVetoablePropertyChange (evt); 346 Element [] newElems = getElements (); 348 evt = new MultiPropertyChangeEvent( 349 members.parentImpl.getElement (), getPropertyName(), oldElems, newElems); 350 evt.makeInsertion (removed, elemsIndexes); 351 members.parentImpl.checkVetoablePropertyChange (evt); 352 } 353 354 failed = false; 355 } else { 356 failed = false; 357 members.parentImpl.throwIsInvalid (); 358 } 359 } catch (InvalidObjectException e) { 360 members.parentImpl.throwIsInvalid (); 361 } finally { 362 members.repository.endTrans (failed); 363 } 364 } 365 366 protected void setMembers (Element[] items) throws SourceException { 367 boolean veto = isClassMember () && ( 368 members.parentImpl.hasVetoableListeners (getPropertyName ()) || 369 members.parentImpl.hasVetoableListeners (ElementProperties.PROP_MEMBERS)); 370 Element [] oldElems = null; 371 Element [] oldMembers = null; 372 373 boolean failed = true; 374 members.repository.beginTrans (true); 375 try { 376 if (isValid()) { 377 members.parentImpl.setClassPath(); 378 if (veto) { 379 oldElems = getElements (); 380 oldMembers = getMembers (); 381 } 382 383 int [] pos; 384 List features = getFeatures (); 385 int size = features.size (); 386 Iterator iter = features.iterator (); 387 List list = new LinkedList (); 388 int posValue = getPositionalValue (); 389 int maxPrevValue = -1; 390 int addIndex = -1; 391 List setFeatures = new LinkedList (); 392 List removedFeatures = new LinkedList (); 393 394 for (int i = 0; i < size; i++) { 395 RefObject feature = (RefObject) iter.next (); 396 int val = getPositionalValue (feature); 397 if ((val <= posValue) && (val > maxPrevValue)) 398 maxPrevValue = val; 399 if (val == maxPrevValue) 400 addIndex = i; 401 if (val == posValue) 402 list.add (new Integer (i)); 403 } 405 int size2 = list.size (); 406 pos = new int [size2]; 407 iter = list.iterator (); 408 for (int i = 0; i < size2; i++) { 409 pos [i] = ((Integer ) iter.next ()).intValue (); 410 } 411 412 ListIterator listIterator = features.listIterator (); 413 int counter = 0; 414 int numToBeSet = Math.min (size2, items.length); 415 if (numToBeSet == 0) { 416 for (int x = 0; x <= addIndex; x++) 418 listIterator.next (); 419 } else { 420 for (int x = 0; x <= pos[numToBeSet-1]; x++) { 422 RefObject refObj = (RefObject) listIterator.next (); 423 if (pos[counter] == x) { 424 listIterator.set ( 425 createFeature (members.javaClass, items[counter]) 426 ); 427 refObj.refDelete (); 428 if (veto) { 429 setFeatures.add (cachedElement (refObj)); 430 } 431 counter++; 432 } 433 addIndex++; 434 } } 436 if (numToBeSet < items.length) { 437 for (int x = numToBeSet; x < items.length; x++) 439 listIterator.add (createFeature (members.javaClass, items[x])); 440 } else if (numToBeSet < size2) { 441 for (int x = pos[numToBeSet-1] + 1; x <= pos[size2-1]; x++) { 443 RefObject refObj = (RefObject) listIterator.next (); 444 if (pos[counter] == x) { 445 listIterator.remove (); 446 refObj.refDelete (); 447 if (veto) { 448 removedFeatures.add (cachedElement (refObj)); 449 } 450 counter++; 451 } 452 } } 454 455 if (veto) { 456 MultiPropertyChangeEvent evt; 457 int [] indexes; 458 int [] setIndexes, removeIndexes, addIndexes = null; 459 setIndexes = removeIndexes = addIndexes = new int [0]; 460 List affectedIndexes = new LinkedList (); 461 Element source = members.parentImpl.getElement (); 462 List evtElems = new LinkedList (); 463 List evtMembers = new LinkedList (); 464 Element [] newMembers = getMembers (); 465 Element [] newElems = getElements (); 466 467 if (numToBeSet > 0) { 468 List curr = new LinkedList (); 469 setIndexes = new int [numToBeSet]; 470 indexes = new int [numToBeSet]; 471 for (int x = 0; x < numToBeSet; x++) { 472 curr.add (items [x]); 473 setIndexes [x] = pos [x]; 474 } 475 evt = new MultiPropertyChangeEvent( 476 source, ElementProperties.PROP_MEMBERS, oldMembers, newMembers); 477 evt.makeReplacement (setFeatures, curr, setIndexes); 478 evtMembers.add (evt); 479 for (int x = 0; x < numToBeSet; x++) { 480 indexes [x] = x; 481 } 482 evt = new MultiPropertyChangeEvent( 483 source, getPropertyName (), oldElems, newElems); 484 evt.makeReplacement (setFeatures, curr, indexes); 485 evtElems.add (evt); 486 } 487 488 addIndex = addIndex + 1; 489 if (numToBeSet < items.length) { 490 List inserted = new LinkedList (); 491 indexes = new int [items.length - numToBeSet]; 492 addIndexes = new int [items.length - numToBeSet]; 493 for (int x = numToBeSet; x < items.length; x++) { 494 inserted.add (items [x]); 495 addIndexes [x - numToBeSet] = addIndex + x - numToBeSet; 496 } 497 evt = new MultiPropertyChangeEvent( 498 source, ElementProperties.PROP_MEMBERS, oldMembers, newMembers); 499 evt.makeInsertion (inserted, addIndexes); 500 evtMembers.add (evt); 501 for (int x = 0; x < items.length - numToBeSet; x++) { 502 indexes [x] = x; 503 } 504 evt = new MultiPropertyChangeEvent( 505 source, getPropertyName (), oldElems, newElems); 506 evt.makeInsertion (inserted, indexes); 507 evtElems.add (evt); 508 } else if (numToBeSet < size2) { 509 indexes = new int [size2 - numToBeSet]; 510 removeIndexes = new int [size2 - numToBeSet]; 511 for (int x = 0; x < size2 - numToBeSet; x++) { 512 removeIndexes [x] = pos [numToBeSet + x]; 513 } 514 evt = new MultiPropertyChangeEvent( 515 source, ElementProperties.PROP_MEMBERS, oldMembers, newMembers); 516 evt.makeRemoval (removedFeatures, removeIndexes); 517 evtMembers.add (evt); 518 for (int x = 0; x < size2 - numToBeSet; x++) { 519 indexes [x] = numToBeSet + x; 520 } 521 evt = new MultiPropertyChangeEvent( 522 source, getPropertyName (), oldElems, newElems); 523 evt.makeRemoval (removedFeatures, indexes); 524 evtElems.add (evt); 525 } 526 527 indexes = new int [setIndexes.length + addIndexes.length + removeIndexes.length]; 528 int i = 0; 529 for (int x = 0; x < setIndexes.length; x++) { 530 indexes [i] = setIndexes [x]; 531 i++; 532 } 533 for (int x = 0; x < addIndexes.length; x++) { 534 indexes [i] = addIndexes [x]; 535 i++; 536 } 537 for (int x = 0; x < removeIndexes.length; x++) { 538 indexes [i] = removeIndexes [x]; 539 i++; 540 } 541 evt = new MultiPropertyChangeEvent( 542 source, ElementProperties.PROP_MEMBERS, oldMembers, newMembers); 543 evt.makeCompound (evtMembers, indexes); 544 members.parentImpl.checkVetoablePropertyChange (evt); 545 546 for (int x = 0; x < indexes.length; x++) 547 indexes [x] = 0; 548 evt = new MultiPropertyChangeEvent( 549 source, getPropertyName (), oldElems, newElems); 550 evt.makeCompound (evtElems, indexes); 551 members.parentImpl.checkVetoablePropertyChange (evt); 552 } 553 554 failed = false; 555 } else { 556 failed = false; 557 members.parentImpl.throwIsInvalid (); 558 } 559 } catch (InvalidObjectException e) { 560 members.parentImpl.throwIsInvalid (); 561 } finally { 562 members.repository.endTrans (failed); 563 } 564 } 565 566 private int findAddPosition (int posValue) { 567 List features = getFeatures (); 568 int size = features.size (); 569 if (size == 0) 570 return 0; 571 572 org.netbeans.jmi.javamodel.Element elems[] = new org.netbeans.jmi.javamodel.Element[size]; 573 Iterator iter = features.iterator (); 574 int maxPrevValue = -1; 575 int index = -1; 576 for (int i = 0; i < size; i++) { 577 org.netbeans.jmi.javamodel.Element feature = (org.netbeans.jmi.javamodel.Element) iter.next (); 578 elems[i] = feature; 579 int val = getPositionalValue (feature); 580 if ((val <= posValue) && (val > maxPrevValue)) 581 maxPrevValue = val; 582 if (val == maxPrevValue) 583 index = i; 584 } 586 591 return index + 1; 592 } 593 594 private int getPositionalValue (RefObject feature) { 595 if (feature instanceof JavaClass) { 596 return POS_VAL_CLASS; 597 } else if (feature instanceof Method) { 598 return POS_VAL_METHOD; 599 } else if (feature instanceof Constructor) { 600 return POS_VAL_CONSTRUCTOR; 601 } else if (feature instanceof Field) { 602 return POS_VAL_FIELD; 603 } else if (feature instanceof Initializer) { 604 return POS_VAL_INITIALIZER; 605 } 606 return POS_VAL_NONE; 607 } 608 609 612 static class FeaturesListener extends ElementImpl.ElementListener { 613 614 static Element [] NO_ELEMENTS = new Element [0]; 615 616 protected ArrayList features; 617 protected boolean fireMembers = true; 618 619 FeaturesListener (ElementImpl impl) { 620 super (impl); 621 } 622 623 public void connect () { 624 if (REGISTER_LISTENER) { 625 try { 626 ((MDRChangeSource) javaElement).addListener (this); 627 features = new ArrayList (); 628 List classFeatures = ((JavaClass) javaElement).getFeatures (); 629 if (classFeatures != null) { 630 features.addAll (classFeatures); 631 } 632 } catch (InvalidObjectException e) { 633 } 635 } 636 } 637 638 private String elemName (RefObject elem) { 639 if (elem == null) 640 return "null"; try { 642 return ((org.netbeans.jmi.javamodel.NamedElement) elem).getName (); 643 } catch (Exception e) { 644 return "deleted"; } 646 } 647 648 protected boolean isWatchedAttribute (AttributeEvent ev) { 649 return ev.getAttributeName ().equals ("contents"); } 651 652 public void doChange(MDRChangeEvent event) { 653 super.doChange (event); 654 if ((event instanceof AttributeEvent) && (isWatchedAttribute((AttributeEvent) event))) { 655 AttributeEvent attribEvent = (AttributeEvent) event; 656 657 RefObject prev = (RefObject) attribEvent.getOldElement (); 658 RefObject curr = (RefObject) attribEvent.getNewElement (); 659 660 663 if (event.isOfType (AttributeEvent.EVENT_ATTRIBUTE_SET)) { 664 doSet (prev, curr); 665 } else if (event.isOfType (AttributeEvent.EVENT_ATTRIBUTE_REMOVE)) { 666 doRemove (prev); 667 } else { doAdd (attribEvent.getPosition (), curr); 669 } 670 671 } } 673 674 public void doSet (RefObject oldFeature, RefObject feature) { 675 677 ObjectsCollection coll = getFeatureCollection (feature); 678 if (coll == null) 679 return; 680 int position = -1; 681 ArrayList temp = new ArrayList (); 682 ArrayList allTemp = new ArrayList (); 683 Iterator iter = features.iterator (); 684 int size = features.size (); 685 int index = -1; 686 for (int x = 0; x < size; x++) { 687 RefObject f = (RefObject) iter.next (); 688 Element elem = cachedElement (f); 689 if (elem != null) { 690 allTemp.add (elem); 691 if (coll.isOfType (f)) { 692 temp.add (elem); 693 } 694 } 695 if (f.equals (oldFeature)) { 696 index = temp.size () - 1; 697 position = x; 698 } 699 } 700 701 if (index == -1) { 702 JMManager.getLog().log(ErrorManager.INFORMATIONAL, "Bad index: " + elemName (feature)); } 704 705 Element oldElem = coll.cachedElement ((RefObject) features.set (position, feature)); 706 Element newElem = (Element) coll.cachedElement (feature); 707 708 if ((oldElem == null) || (newElem == null)) { 709 return; 711 } 712 713 Object old = temp.toArray (NO_ELEMENTS); 714 List orig = new LinkedList (); 715 List replacement = new LinkedList (); 716 orig.add (oldElem); 717 replacement.add (newElem); 718 temp.set (index, newElem); 719 Object now = temp.toArray (NO_ELEMENTS); 720 721 if (fireMembers) { 722 Element [] allOld = (Element []) allTemp.toArray (NO_ELEMENTS); 723 allTemp.set (position, newElem); 724 Element [] allNew = (Element []) allTemp.toArray (NO_ELEMENTS); 725 MultiPropertyChangeEvent mEvt = new MultiPropertyChangeEvent( 726 impl.getElement (), ElementProperties.PROP_MEMBERS, allOld, allNew); 727 mEvt.makeReplacement(orig, replacement, new int [] {position}); 728 729 impl.fireOwnPropertyChange (mEvt); 730 } 731 732 MultiPropertyChangeEvent evt = new MultiPropertyChangeEvent( 733 impl.getElement (), coll.getPropertyName(), old, now); 734 evt.makeReplacement(orig, replacement, new int [] {index}); 735 impl.fireOwnPropertyChange (evt); 736 impl.notifyConnectionSet (oldElem, newElem); 737 } 738 739 public void doAdd (int position, RefObject feature) { 740 741 743 int size = features.size(); 744 if (position == -1 || position > size) 746 position = size; 747 ObjectsCollection coll = getFeatureCollection(feature); 748 if (coll == null) 749 return; 750 ArrayList temp = new ArrayList(); 751 ArrayList allTemp = new ArrayList(); 752 Iterator iter = features.iterator(); 753 int index = -1; 754 for (int x = 0; x < size; x++) { 755 RefObject f = (RefObject) iter.next (); 756 Element elem = cachedElement(f); 757 if (elem != null) { 758 allTemp.add (elem); 759 if (coll.isOfType (f)) { 760 temp.add (elem); 761 } 762 } 763 if (x == position) { 764 index = temp.size (); 765 } 766 } 767 if (index == -1) 768 index = temp.size (); 769 770 features.add (position, feature); 771 Element addedElem = (Element) coll.cachedElement (feature); 772 773 if (addedElem == null) { 774 return; 776 } 777 778 Object old = temp.toArray (NO_ELEMENTS); 779 List added = new LinkedList (); 780 added.add (addedElem); 781 temp.add (index, addedElem); 782 Object newElems = temp.toArray (NO_ELEMENTS); 783 784 if (fireMembers) { 785 Element [] allOld = (Element []) allTemp.toArray (NO_ELEMENTS); 786 allTemp.add (position, addedElem); 787 Element [] allNew = (Element []) allTemp.toArray (NO_ELEMENTS); 788 MultiPropertyChangeEvent mEvt = new MultiPropertyChangeEvent( 789 impl.getElement (), ElementProperties.PROP_MEMBERS, allOld, allNew); 790 mEvt.makeInsertion(added, new int [] {position}); 791 792 impl.fireOwnPropertyChange (mEvt); 793 } 794 795 MultiPropertyChangeEvent evt = new MultiPropertyChangeEvent( 796 impl.getElement (), coll.getPropertyName(), old, newElems); 797 evt.makeInsertion(added, new int [] {index}); 798 impl.fireOwnPropertyChange (evt); 799 impl.notifyConnectionAdd (addedElem); 800 } 801 802 public void doRemove (RefObject member) { 803 805 int position = -1; 806 ObjectsCollection coll = getFeatureCollection (member); 807 if (coll == null) 808 return; 809 ArrayList temp = new ArrayList (); 810 ArrayList allTemp = new ArrayList (); 811 812 Iterator iter = features.iterator (); 813 int size = features.size (); 814 int index = -1; 815 for (int x = 0; x < size; x++) { 816 RefObject feature = (RefObject) iter.next (); 817 Element elem = cachedElement (feature); 818 if (elem != null) { 819 allTemp.add (elem); 820 if (coll.isOfType (feature)) { 821 temp.add (elem); 822 } 823 } 824 if (member.equals (feature)) { 825 index = temp.size () - 1; 826 position = x; 827 } 828 } 829 830 if (position == -1) { 831 JMManager.getLog().log(ErrorManager.INFORMATIONAL, "Bad index: " + elemName (member)); return; } 834 835 features.remove (position); 836 837 if (cachedElement(member) == null) { 838 return; 840 } 841 842 Element [] old = (Element []) temp.toArray (NO_ELEMENTS); 843 Element o = (Element) temp.remove (index); 844 List removed = new LinkedList (); 845 removed.add (o); 846 Element [] newElems = (Element []) temp.toArray (NO_ELEMENTS); 847 848 855 if (fireMembers) { 856 Element [] allOld = (Element []) allTemp.toArray (NO_ELEMENTS); 857 allTemp.remove (position); 858 Element [] allNew = (Element []) allTemp.toArray (NO_ELEMENTS); 859 MultiPropertyChangeEvent mEvt = new MultiPropertyChangeEvent( 860 impl.getElement (), ElementProperties.PROP_MEMBERS, allOld, allNew); 861 mEvt.makeRemoval(removed, new int [] {position}); 862 863 impl.fireOwnPropertyChange (mEvt); 864 } 865 866 MultiPropertyChangeEvent evt = new MultiPropertyChangeEvent( 867 impl.getElement (), coll.getPropertyName(), old, newElems); 868 evt.makeRemoval(removed, new int [] {index}); 869 870 impl.fireOwnPropertyChange (evt); 871 impl.notifyConnectionRemove (o); 872 } 873 874 public ObjectsCollection getFeatureCollection (RefObject feature) { 875 if (feature instanceof JavaClass) { 876 return ((ClassElementImpl) impl).innerClasses; 877 } else if (feature instanceof Method) { 878 return ((ClassElementImpl) impl).methods; 879 } else if (feature instanceof Constructor) { 880 return ((ClassElementImpl) impl).constructors; 881 } else if (feature instanceof Field) { 882 return ((ClassElementImpl) impl).fields; 883 } else if (feature instanceof Initializer) { 884 return ((ClassElementImpl) impl).initializers; 885 } 886 return null; 887 } 888 889 public Element cachedElement (RefObject f) { 890 if (f instanceof JavaClass) { 891 return ((ClassElementImpl) impl).innerClasses.cachedElement (f); 892 } else if (f instanceof Method) { 893 return ((ClassElementImpl) impl).methods.cachedElement (f); 894 } else if (f instanceof Constructor) { 895 return ((ClassElementImpl) impl).constructors.cachedElement (f); 896 } else if (f instanceof Field) { 897 return ((ClassElementImpl) impl).fields.cachedElement (f); 898 } else if (f instanceof Initializer) { 899 return ((ClassElementImpl) impl).initializers.cachedElement (f); 900 } 901 return null; 902 } 903 } 904 } 905 | Popular Tags |