KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > java > bridge > ObjectsCollection


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.java.bridge;
21
22 import java.lang.ref.WeakReference JavaDoc;
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     // ..........................................................................
53

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 JavaDoc getPropertyName ();
65     
66     public abstract boolean isOfType (RefObject feature);
67     
68     protected Element cachedElement (RefObject refObject) { // [PENDING] synchronization
69
Element elem;
70         WeakReference JavaDoc ref = (WeakReference JavaDoc) 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 JavaDoc (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 () { // should be abstract
103
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 JavaDoc ();
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 JavaDoc ("null element in " + items.getClass ().getName ()); // NOI18N
162

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 JavaDoc("Unknown/unsupported operation: " + operation); // NOI18N
175
}
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 JavaDoc 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                     // PROP_MEMBERS
212
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                     // PROP_XXXS (XXX = feature name)
221
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 JavaDoc 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"; // NOI18N
278
} else { // ImportElement
279
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"; // NOI18N
298
else if (f instanceof org.netbeans.jmi.javamodel.Import) {
299                             name = ((org.netbeans.jmi.javamodel.Import) f).getName ();
300                             if (name.endsWith (".*")) { // NOI18N
301
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                                 } // if (matches (...))
327
} // while
328
} // if (list != null)
329
elemsCounter ++;
330                     } // if (isOfType (f))
331
membersCounter ++;
332                 } // while
333
if (map.size () > 0) {
334                     throw new SourceException ("An element to be removed not found."); // NOI18N
335
}
336
337                 if (veto) {
338                     MultiPropertyChangeEvent evt;
339                     List removed = Arrays.asList (items);
340                     // PROP_MEMBERS
341
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                     // PROP_XXXS (XXX = feature name)
347
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 JavaDoc (i));
403                 } // for
404

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 JavaDoc) 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                     // go to add position
417
for (int x = 0; x <= addIndex; x++)
418                         listIterator.next ();
419                 } else {
420                     // do SET
421
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                     } // for
435
}
436                 if (numToBeSet < items.length) {
437                     // do ADD
438
for (int x = numToBeSet; x < items.length; x++)
439                         listIterator.add (createFeature (members.javaClass, items[x]));
440                 } else if (numToBeSet < size2) {
441                     // do REMOVE
442
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                     } // for
453
}
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         } // for
585

586 // JavaMetamodel manager = JavaMetamodel.getManager();
587
// while (index >= 0 && manager.isElementGuarded(elems[index])) {
588
// index--;
589
// }
590

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     // ..........................................................................
610
// ..........................................................................
611

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                     // [PENDING]
634
}
635             }
636         }
637         
638         private String JavaDoc elemName (RefObject elem) {
639             if (elem == null)
640                 return "null"; // NOI18N
641
try {
642                 return ((org.netbeans.jmi.javamodel.NamedElement) elem).getName ();
643             } catch (Exception JavaDoc e) {
644                 return "deleted"; // NOI18N
645
}
646         }
647
648         protected boolean isWatchedAttribute (AttributeEvent ev) {
649             return ev.getAttributeName ().equals ("contents"); // NOI18N
650
}
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                 //System.out.println("FeaturesListener: " + assocEvent.getPosition () + " " + assocEvent.getEndName () + " " +
661
//elemName (fixed) + " " + elemName (prev) + " " + elemName (curr) + " " + hashCode ());
662

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 { // EVENT_ASSOCIATION_ADD
668
doAdd (attribEvent.getPosition (), curr);
669                 }
670
671             } // if
672
}
673
674         public void doSet (RefObject oldFeature, RefObject feature) {
675             // System.out.println("doSet: " + elemName (feature));
676

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)); // NOI18N
703
}
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                 // can occure in case of TopClassesCollection when related classifiers contain a non JavaClass element
710
return;
711             }
712             
713             Object JavaDoc 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 JavaDoc 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             // System.out.println("doAdd: " + elemName (feature) + " " + position);
742

743             int size = features.size();
744             // [PENDING]
745
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                 // can occure in case of TopClassesCollection when related classifiers contain a non JavaClass element
775
return;
776             }
777             
778             Object JavaDoc old = temp.toArray (NO_ELEMENTS);
779             List added = new LinkedList ();
780             added.add (addedElem);
781             temp.add (index, addedElem);
782             Object JavaDoc 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             // System.out.println("doRemove: " + elemName (member) + hashCode ());
804

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)); // NOI18N
832
return; // [PENDING]
833
}
834             
835             features.remove (position);
836             
837             if (cachedElement(member) == null) {
838                 // can occure in case of TopClassesCollection when related classifiers contain a non JavaClass element
839
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             //System.out.println("\t" + old.length);
849
//System.out.print("\t");
850
//for (int x = 0; x < newElems.length; x++)
851
//System.out.print(((MemberElement) newElems[x]).getName () + " ");
852
//System.out.println("");
853
//System.out.println("\t" + index);
854

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