KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > emf > ecore > util > DelegatingFeatureMap


1 /**
2  * <copyright>
3  *
4  * Copyright (c) 2003-2004 IBM Corporation and others.
5  * All rights reserved. This program and the accompanying materials
6  * are made available under the terms of the Eclipse Public License v1.0
7  * which accompanies this distribution, and is available at
8  * http://www.eclipse.org/legal/epl-v10.html
9  *
10  * Contributors:
11  * IBM - Initial API and implementation
12  *
13  * </copyright>
14  *
15  * $Id: DelegatingFeatureMap.java,v 1.18 2005/06/12 13:29:22 emerks Exp $
16  */

17 package org.eclipse.emf.ecore.util;
18
19
20
21 import java.util.Collection JavaDoc;
22 import java.util.Collections JavaDoc;
23 import java.util.Iterator JavaDoc;
24 import java.util.List JavaDoc;
25 import java.util.ListIterator JavaDoc;
26
27 import org.eclipse.emf.common.notify.Notification;
28 import org.eclipse.emf.common.notify.NotificationChain;
29 import org.eclipse.emf.common.notify.impl.NotificationImpl;
30 import org.eclipse.emf.common.util.BasicEList;
31 import org.eclipse.emf.common.util.EList;
32 import org.eclipse.emf.ecore.EClassifier;
33 import org.eclipse.emf.ecore.EObject;
34 import org.eclipse.emf.ecore.EReference;
35 import org.eclipse.emf.ecore.EStructuralFeature;
36 import org.eclipse.emf.ecore.InternalEObject;
37 import org.eclipse.emf.ecore.impl.ENotificationImpl;
38
39
40
41 public abstract class DelegatingFeatureMap extends DelegatingEcoreEList implements FeatureMap.Internal
42 {
43   protected final FeatureMapUtil.Validator featureMapValidator;
44   protected final EStructuralFeature eStructuralFeature;
45
46   public DelegatingFeatureMap(InternalEObject owner, int featureID)
47   {
48     super(owner);
49     this.eStructuralFeature = owner.eClass().getEStructuralFeature(featureID);
50     featureMapValidator = FeatureMapUtil.getValidator(owner.eClass(), getEStructuralFeature());
51   }
52
53   public DelegatingFeatureMap(InternalEObject owner, EStructuralFeature eStructuralFeature)
54   {
55     super(owner);
56     this.eStructuralFeature = eStructuralFeature;
57     featureMapValidator = FeatureMapUtil.getValidator(owner.eClass(), getEStructuralFeature());
58   }
59
60 /*
61   List theList = new java.util.ArrayList();
62   protected List delegateList()
63   {
64     return theList;
65   }
66 */

67
68   protected Object JavaDoc validate(int index, Object JavaDoc object)
69   {
70     Object JavaDoc result = super.validate(index, object);
71     EStructuralFeature eStructuralFeature = ((Entry)object).getEStructuralFeature();
72     if (!eStructuralFeature.isChangeable() || !featureMapValidator.isValid(eStructuralFeature))
73     {
74       throw
75         new RuntimeException JavaDoc
76           ("Invalid entry feature '" + eStructuralFeature.getEContainingClass().getName() + "." + eStructuralFeature.getName() + "'");
77     }
78     return result;
79   }
80
81   protected boolean isEObject()
82   {
83     return false;
84   }
85
86   protected boolean isUnique()
87   {
88     return false;
89   }
90
91   protected boolean canContainNull()
92   {
93     return false;
94   }
95
96   protected EClassifier getFeatureType()
97   {
98     return org.eclipse.emf.ecore.EcorePackage.eINSTANCE.getEJavaObject();
99   }
100
101   public EStructuralFeature getEStructuralFeature()
102   {
103     return eStructuralFeature;
104   }
105
106   protected FeatureMap.Entry createEntry(EStructuralFeature eStructuralFeature, Object JavaDoc value)
107   {
108     return FeatureMapUtil.createEntry(eStructuralFeature, value);
109   }
110
111   protected NotificationImpl createNotification
112     (int eventType, EStructuralFeature feature, Object JavaDoc oldObject, Object JavaDoc newObject, int index, boolean wasSet)
113   {
114     return new FeatureMapUtil.FeatureENotificationImpl(owner, eventType, feature, oldObject, newObject, index, wasSet);
115   }
116
117   protected boolean isMany(EStructuralFeature feature)
118   {
119     return FeatureMapUtil.isMany(owner, feature);
120   }
121
122   protected boolean hasInverse()
123   {
124     return true;
125   }
126
127   protected boolean hasShadow()
128   {
129     return true;
130   }
131
132   protected int entryIndex(EStructuralFeature feature, int index)
133   {
134     FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
135     int count = 0;
136     int size = delegateSize();
137     int result = size;
138     for (int i = 0; i < size; ++i)
139     {
140       Entry entry = (Entry)delegateGet(i);
141       if (validator.isValid(entry.getEStructuralFeature()))
142       {
143         if (index == count)
144         {
145           return i;
146         }
147         ++count;
148         result = i + 1;
149       }
150     }
151
152     if (index == count)
153     {
154       return result;
155     }
156     else
157     {
158       throw new IndexOutOfBoundsException JavaDoc("index=" + index + ", size=" + count);
159     }
160   }
161
162   protected boolean isResolveProxies(EStructuralFeature feature)
163   {
164     return feature instanceof EReference && ((EReference)feature).isResolveProxies();
165   }
166
167   public Object JavaDoc resolveProxy(EStructuralFeature feature, int entryIndex, int index, Object JavaDoc object)
168   {
169     EObject resolved = resolveProxy((EObject)object);
170     if (resolved != object)
171     {
172       Object JavaDoc oldObject = delegateGet(entryIndex);
173       Entry entry = createEntry(feature, resolved);
174       delegateSet(entryIndex, validate(entryIndex, entry));
175       didSet(entryIndex, entry, oldObject);
176
177       if (isNotificationRequired())
178       {
179         NotificationImpl notifications =
180           createNotification
181             (Notification.RESOLVE,
182              entry.getEStructuralFeature(),
183              object,
184              resolved,
185              index,
186              false);
187
188         notifications.add(createNotification(Notification.RESOLVE, oldObject, entry, index, false));
189         notifications.dispatch();
190       }
191
192       return resolved;
193     }
194
195     return object;
196   }
197
198   protected EObject resolveProxy(EObject eObject)
199   {
200     return owner.eResolveProxy((InternalEObject)eObject);
201   }
202
203   public int getModCount()
204   {
205     return modCount;
206   }
207
208   public EStructuralFeature getEStructuralFeature(int index)
209   {
210     return ((Entry)get(index)).getEStructuralFeature();
211   }
212
213   public Object JavaDoc getValue(int index)
214   {
215     return ((Entry)get(index)).getValue();
216   }
217
218   public Object JavaDoc setValue(int index, Object JavaDoc value)
219   {
220     return ((Entry)set(index, createEntry(getEStructuralFeature(index), value))).getValue();
221   }
222
223   public NotificationChain shadowAdd(Object JavaDoc object, NotificationChain notifications)
224   {
225     if (isNotificationRequired())
226     {
227       Entry entry = (Entry)object;
228       EStructuralFeature feature = entry.getEStructuralFeature();
229       Object JavaDoc value = entry.getValue();
230       // EATM must fix isSet bits.
231
NotificationImpl notification =
232         feature.isMany() ?
233           createNotification
234             (Notification.ADD,
235              feature,
236              null,
237              value,
238              indexOf(feature, value),
239              true) :
240           createNotification
241             (Notification.SET,
242              feature,
243              feature.getDefaultValue(),
244              value,
245              Notification.NO_INDEX,
246              true);
247   
248       if (notifications != null)
249       {
250         notifications.add(notification);
251       }
252       else
253       {
254         notifications = notification;
255       }
256     }
257     return notifications;
258   }
259
260   public NotificationChain inverseAdd(Object JavaDoc object, NotificationChain notifications)
261   {
262     Entry entry = (Entry)object;
263     EStructuralFeature feature = entry.getEStructuralFeature();
264     if (feature instanceof EReference)
265     {
266       EReference eReference = (EReference)feature;
267       EReference eOpposite = eReference.getEOpposite();
268       if (eOpposite != null)
269       {
270         InternalEObject internalEObject = (InternalEObject)entry.getValue();
271         if (internalEObject != null)
272         {
273           notifications =
274             internalEObject.eInverseAdd
275               (owner,
276                internalEObject.eClass().getFeatureID(eOpposite),
277                null,
278                notifications);
279         }
280       }
281       else if (eReference.isContainment())
282       {
283         InternalEObject internalEObject = (InternalEObject)entry.getValue();
284         if (internalEObject != null)
285         {
286           int containmentFeatureID = owner.eClass().getFeatureID(eReference);
287           notifications =
288             internalEObject.eInverseAdd
289               (owner,
290                InternalEObject.EOPPOSITE_FEATURE_BASE - (containmentFeatureID == -1 ? getFeatureID() : containmentFeatureID),
291                null,
292                notifications);
293         }
294       }
295     }
296
297     return notifications;
298   }
299
300   public NotificationChain shadowRemove(Object JavaDoc object, NotificationChain notifications)
301   {
302     if (isNotificationRequired())
303     {
304       Entry entry = (Entry)object;
305       EStructuralFeature feature = entry.getEStructuralFeature();
306       Object JavaDoc value = entry.getValue();
307       NotificationImpl notification =
308         feature.isMany() ?
309           createNotification
310             (Notification.REMOVE,
311              feature,
312              value,
313              null,
314              indexOf(feature, value),
315              true) :
316           createNotification
317             (feature.isUnsettable() ? Notification.UNSET : Notification.SET,
318              feature,
319              value,
320              feature.getDefaultValue(),
321              Notification.NO_INDEX,
322              true);
323
324       if (notifications != null)
325       {
326         notifications.add(notification);
327       }
328       else
329       {
330         notifications = notification;
331       }
332     }
333     return notifications;
334   }
335
336   public NotificationChain inverseRemove(Object JavaDoc object, NotificationChain notifications)
337   {
338     Entry entry = (Entry)object;
339     EStructuralFeature feature = entry.getEStructuralFeature();
340     if (feature instanceof EReference)
341     {
342       EReference eReference = (EReference)feature;
343       EReference eOpposite = eReference.getEOpposite();
344       if (eOpposite != null)
345       {
346         InternalEObject internalEObject = (InternalEObject)entry.getValue();
347         if (internalEObject != null)
348         {
349           notifications =
350             internalEObject.eInverseRemove
351               (owner,
352                internalEObject.eClass().getFeatureID(eOpposite),
353                null,
354                notifications);
355         }
356       }
357       else if (eReference.isContainment())
358       {
359         InternalEObject internalEObject = (InternalEObject)entry.getValue();
360         if (internalEObject != null)
361         {
362           int containmentFeatureID = owner.eClass().getFeatureID(eReference);
363           notifications =
364             internalEObject.eInverseRemove
365               (owner,
366                InternalEObject.EOPPOSITE_FEATURE_BASE - (containmentFeatureID == -1 ? getFeatureID() : containmentFeatureID),
367                null,
368                notifications);
369         }
370       }
371     }
372     return notifications;
373   }
374
375   public NotificationChain shadowSet(Object JavaDoc oldObject, Object JavaDoc newObject, NotificationChain notifications)
376   {
377     if (isNotificationRequired())
378     {
379       Entry entry = (Entry)oldObject;
380       EStructuralFeature feature = entry.getEStructuralFeature();
381       Object JavaDoc oldValue = entry.getValue();
382       Object JavaDoc newValue = ((Entry)newObject).getValue();
383       NotificationImpl notification =
384         createNotification
385           (Notification.SET,
386            feature,
387            oldValue,
388            newValue,
389            feature.isMany() ? indexOf(feature, newValue) : Notification.NO_INDEX,
390            true);
391
392       if (notifications != null)
393       {
394         notifications.add(notification);
395       }
396       else
397       {
398         notifications = notification;
399       }
400     }
401     return notifications;
402   }
403
404   public NotificationChain inverseTouch(Object JavaDoc object, NotificationChain notifications)
405   {
406     if (isNotificationRequired())
407     {
408       Entry entry = (Entry)object;
409       EStructuralFeature feature = entry.getEStructuralFeature();
410       Object JavaDoc value = entry.getValue();
411       NotificationImpl notification =
412         createNotification
413           (Notification.SET,
414            feature,
415            value,
416            value,
417            feature.isMany() ? indexOf(feature, value) : Notification.NO_INDEX,
418            true);
419   
420       if (notifications != null)
421       {
422         notifications.add(notification);
423       }
424       else
425       {
426         notifications = notification;
427       }
428     }
429
430     return notifications;
431   }
432
433   public Object JavaDoc move(int targetIndex, int sourceIndex)
434   {
435     if (isNotificationRequired())
436     {
437       Entry sourceEntry = (Entry)delegateGet(sourceIndex);
438       EStructuralFeature feature = sourceEntry.getEStructuralFeature();
439       if (isMany(feature))
440       {
441         FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
442         int featureTargetIndex = -1;
443         int featureSourceIndex = -1;
444         int count = 0;
445         for (int i = 0, size = delegateSize(); i < size; ++i)
446         {
447           Entry entry = (Entry)delegateGet(i);
448           if (i == targetIndex)
449           {
450             featureTargetIndex = count;
451           }
452           if (i == sourceIndex)
453           {
454             featureSourceIndex = count;
455           }
456           if (validator.isValid(entry.getEStructuralFeature()))
457           {
458             ++count;
459           }
460         }
461
462         Object JavaDoc result = doMove(targetIndex, sourceIndex);
463         if (featureSourceIndex != featureTargetIndex)
464         {
465           dispatchNotification
466             (new ENotificationImpl
467                (owner,
468                 Notification.MOVE,
469                 feature,
470                 new Integer JavaDoc(featureSourceIndex),
471                 sourceEntry.getValue(),
472                 featureTargetIndex));
473         }
474         return result;
475       }
476       else
477       {
478         return doMove(targetIndex, sourceIndex);
479       }
480     }
481     else
482     {
483       return doMove(targetIndex, sourceIndex);
484     }
485   }
486
487   protected Object JavaDoc doMove(int targetIndex, int sourceIndex)
488   {
489     return super.move(targetIndex, sourceIndex);
490   }
491
492   public Object JavaDoc set(int index, Object JavaDoc object)
493   {
494     Entry entry = (Entry)object;
495     EStructuralFeature entryFeature = entry.getEStructuralFeature();
496     if (isMany(entryFeature))
497     {
498       if (entryFeature.isUnique())
499       {
500         for (int i = 0, size = delegateSize(); i < size; ++i)
501         {
502           Entry otherEntry = (Entry)delegateGet(i);
503           if (otherEntry.equals(entry) && i != index)
504           {
505             throw new IllegalArgumentException JavaDoc("The 'no duplicates' constraint is violated");
506           }
507         }
508       }
509     }
510     else
511     {
512       FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), entryFeature);
513       for (int i = 0, size = delegateSize(); i < size; ++i)
514       {
515         Entry otherEntry = (Entry)delegateGet(i);
516         if (validator.isValid(otherEntry.getEStructuralFeature()) && i != index)
517         {
518           throw new IllegalArgumentException JavaDoc("The multiplicity constraint is violated");
519         }
520       }
521     }
522
523     return doSet(index, object);
524   }
525
526   public Object JavaDoc doSet(int index, Object JavaDoc object)
527   {
528     return super.set(index, object);
529   }
530
531   public boolean add(Object JavaDoc object)
532   {
533     Entry entry = (Entry)object;
534     EStructuralFeature entryFeature = entry.getEStructuralFeature();
535     if (isMany(entryFeature))
536     {
537       if (entryFeature.isUnique() && contains(entryFeature, entry.getValue()))
538       {
539         return false;
540       }
541     }
542     else
543     {
544       FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), entryFeature);
545       for (int i = 0, size = delegateSize(); i < size; ++i)
546       {
547         Entry otherEntry = (Entry)delegateGet(i);
548         if (validator.isValid(otherEntry.getEStructuralFeature()))
549         {
550           if (otherEntry.equals(entry))
551           {
552             return false;
553           }
554           else
555           {
556             doSet(i, object);
557             return true;
558           }
559         }
560       }
561     }
562
563     return doAdd(object);
564   }
565
566   protected boolean doAdd(Object JavaDoc object)
567   {
568     return super.add(object);
569   }
570
571   public void add(int index, Object JavaDoc object)
572   {
573     Entry entry = (Entry)object;
574     EStructuralFeature entryFeature = entry.getEStructuralFeature();
575     if (isMany(entryFeature))
576     {
577       if (entryFeature.isUnique())
578       {
579         for (int i = 0, size = delegateSize(); i < size; ++i)
580         {
581           Entry otherEntry = (Entry)delegateGet(i);
582           if (otherEntry.equals(entry) && i != index)
583           {
584             throw new IllegalArgumentException JavaDoc("The 'no duplicates' constraint is violated");
585           }
586         }
587       }
588     }
589     else
590     {
591       FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), entryFeature);
592       for (int i = 0, size = delegateSize(); i < size; ++i)
593       {
594         Entry otherEntry = (Entry)delegateGet(i);
595         if (validator.isValid(otherEntry.getEStructuralFeature()))
596         {
597           throw new IllegalArgumentException JavaDoc("The multiplicity constraint is violated");
598         }
599       }
600     }
601
602     doAdd(index, object);
603   }
604
605   public void doAdd(int index, Object JavaDoc object)
606   {
607     super.add(index, object);
608   }
609
610   public boolean addAll(Collection JavaDoc collection)
611   {
612     Collection JavaDoc uniqueCollection = new BasicEList(collection.size());
613     for (Iterator JavaDoc i = collection.iterator(); i.hasNext(); )
614     {
615       Entry entry = (Entry)i.next();
616       EStructuralFeature entryFeature = entry.getEStructuralFeature();
617       if (isMany(entryFeature))
618       {
619         if (!entryFeature.isUnique() || !contains(entryFeature, entry.getValue()) && !uniqueCollection.contains(entry))
620         {
621           uniqueCollection.add(entry);
622         }
623       }
624       else
625       {
626         FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), entryFeature);
627         boolean include = true;
628         for (int j = 0, size = delegateSize(); j < size; ++j)
629         {
630           Entry otherEntry = (Entry)delegateGet(j);
631           if (validator.isValid(otherEntry.getEStructuralFeature()))
632           {
633             doSet(j, entry);
634             include = false;
635             break;
636           }
637         }
638         if (include)
639         {
640           uniqueCollection.add(entry);
641         }
642       }
643     }
644
645     return doAddAll(uniqueCollection);
646   }
647
648   public boolean doAddAll(Collection JavaDoc collection)
649   {
650     return super.addAll(collection);
651   }
652
653   public boolean addAll(int index, Collection JavaDoc collection)
654   {
655     Collection JavaDoc uniqueCollection = new BasicEList(collection.size());
656     for (Iterator JavaDoc i = collection.iterator(); i.hasNext(); )
657     {
658       Entry entry = (Entry)i.next();
659       EStructuralFeature entryFeature = entry.getEStructuralFeature();
660       if (isMany(entryFeature))
661       {
662         if (!entryFeature.isUnique() || !contains(entryFeature, entry.getValue()) && !uniqueCollection.contains(entry))
663         {
664           uniqueCollection.add(entry);
665         }
666       }
667       else
668       {
669         FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), entryFeature);
670         boolean include = true;
671         for (int j = 0, size = delegateSize(); j < size; ++j)
672         {
673           Entry otherEntry = (Entry)delegateGet(j);
674           if (validator.isValid(otherEntry.getEStructuralFeature()))
675           {
676             doSet(j, entry);
677             include = false;
678             break;
679           }
680         }
681         if (include)
682         {
683           uniqueCollection.add(entry);
684         }
685       }
686     }
687
688     return doAddAll(index, uniqueCollection);
689   }
690
691   public boolean doAddAll(int index, Collection JavaDoc collection)
692   {
693     return super.addAll(index, collection);
694   }
695
696
697   public int size(EStructuralFeature feature)
698   {
699     FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
700     int result = 0;
701     for (int i = 0, size = delegateSize(); i < size; ++i)
702     {
703       Entry entry = (Entry)delegateGet(i);
704       if (validator.isValid(entry.getEStructuralFeature()))
705       {
706         ++result;
707       }
708     }
709     return result;
710   }
711
712   public boolean isEmpty(EStructuralFeature feature)
713   {
714     FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
715     for (int i = 0, size = delegateSize(); i < size; ++i)
716     {
717       Entry entry = (Entry)delegateGet(i);
718       if (validator.isValid(entry.getEStructuralFeature()))
719       {
720         return false;
721       }
722     }
723     return true;
724   }
725
726   public boolean contains(EStructuralFeature feature, Object JavaDoc object)
727   {
728     FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
729     if (FeatureMapUtil.isFeatureMap(feature))
730     {
731       for (int i = 0, size = delegateSize(); i < size; ++i)
732       {
733         Entry entry = (Entry)delegateGet(i);
734         if (validator.isValid(entry.getEStructuralFeature()) && entry.equals(object))
735         {
736           return true;
737         }
738       }
739     }
740     else if (object != null)
741     {
742       for (int i = 0, size = delegateSize(); i < size; ++i)
743       {
744         Entry entry = (Entry)delegateGet(i);
745         if (validator.isValid(entry.getEStructuralFeature()) && object.equals(entry.getValue()))
746         {
747           return true;
748         }
749       }
750     }
751     else
752     {
753       for (int i = 0, size = delegateSize(); i < size; ++i)
754       {
755         Entry entry = (Entry)delegateGet(i);
756         if (validator.isValid(entry.getEStructuralFeature()) && entry.getValue() == null)
757         {
758           return false;
759         }
760       }
761     }
762
763     return false;
764   }
765
766   public boolean containsAll(EStructuralFeature feature, Collection JavaDoc collection)
767   {
768     for (Iterator JavaDoc i = collection.iterator(); i.hasNext(); )
769     {
770       if (!contains(feature, i.next()))
771       {
772         return false;
773       }
774     }
775
776     return true;
777   }
778
779   public int indexOf(EStructuralFeature feature, Object JavaDoc object)
780   {
781     FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
782     int result = 0;
783     if (FeatureMapUtil.isFeatureMap(feature))
784     {
785       for (int i = 0, size = delegateSize(); i < size; ++i)
786       {
787         Entry entry = (Entry)delegateGet(i);
788         if (validator.isValid(entry.getEStructuralFeature()))
789         {
790           if (entry.equals(object))
791           {
792             return result;
793           }
794           ++result;
795         }
796       }
797     }
798     else if (object != null)
799     {
800       for (int i = 0, size = delegateSize(); i < size; ++i)
801       {
802         Entry entry = (Entry)delegateGet(i);
803         if (validator.isValid(entry.getEStructuralFeature()))
804         {
805           if (object.equals(entry.getValue()))
806           {
807             return result;
808           }
809           ++result;
810         }
811       }
812     }
813     else
814     {
815       for (int i = 0, size = delegateSize(); i < size; ++i)
816       {
817         Entry entry = (Entry)delegateGet(i);
818         if (validator.isValid(entry.getEStructuralFeature()))
819         {
820           if (entry.getValue() == null)
821           {
822             return result;
823           }
824           ++result;
825         }
826       }
827     }
828
829     return -1;
830   }
831
832   public int lastIndexOf(EStructuralFeature feature, Object JavaDoc object)
833   {
834     FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
835     int result = -1;
836     int count = 0;
837     if (FeatureMapUtil.isFeatureMap(feature))
838     {
839       for (int i = 0, size = delegateSize(); i < size; ++i)
840       {
841         Entry entry = (Entry)delegateGet(i);
842         if (validator.isValid(entry.getEStructuralFeature()))
843         {
844           if (entry.equals(object))
845           {
846             result = count;
847           }
848           ++count;
849         }
850       }
851     }
852     else if (object != null)
853     {
854       for (int i = 0, size = delegateSize(); i < size; ++i)
855       {
856         Entry entry = (Entry)delegateGet(i);
857         if (validator.isValid(entry.getEStructuralFeature()))
858         {
859           if (object.equals(entry.getValue()))
860           {
861             result = count;
862           }
863           ++count;
864         }
865       }
866     }
867     else
868     {
869       for (int i = 0, size = delegateSize(); i < size; ++i)
870       {
871         Entry entry = (Entry)delegateGet(i);
872         if (validator.isValid(entry.getEStructuralFeature()))
873         {
874           if (entry.getValue() == null)
875           {
876             result = count;
877           }
878           ++count;
879         }
880       }
881     }
882
883     return result;
884   }
885
886   public Iterator JavaDoc iterator(EStructuralFeature feature)
887   {
888     return
889       feature instanceof EReference && ((EReference)feature).isResolveProxies() ?
890         new ResolvingFeatureEIterator(feature, this) :
891         new FeatureEIterator(feature, this);
892   }
893
894   public ListIterator JavaDoc listIterator(EStructuralFeature feature)
895   {
896     return
897       feature instanceof EReference && ((EReference)feature).isResolveProxies() ?
898         new ResolvingFeatureEIterator(feature, this) :
899         new FeatureEIterator(feature, this);
900   }
901
902   public ListIterator JavaDoc listIterator(EStructuralFeature feature, int index)
903   {
904     ListIterator JavaDoc result =
905       feature instanceof EReference && ((EReference)feature).isResolveProxies() ?
906         new ResolvingFeatureEIterator(feature, this) :
907         new FeatureEIterator(feature, this);
908     for (int i = 0; i < index; ++i)
909     {
910       result.next();
911     }
912     return result;
913   }
914
915   public ValueListIterator valueListIterator()
916   {
917     return new ValueListIteratorImpl();
918   }
919   
920   public ValueListIterator valueListIterator(int index)
921   {
922     return new ValueListIteratorImpl(index);
923   }
924   
925   protected class ValueListIteratorImpl extends EListIterator implements ValueListIterator
926   {
927     public ValueListIteratorImpl()
928     {
929       super();
930     }
931     
932     public ValueListIteratorImpl(int index)
933     {
934       super(index);
935     }
936     
937     public EStructuralFeature feature()
938     {
939       if (lastCursor == -1)
940       {
941         throw new IllegalStateException JavaDoc();
942       }
943       return getEStructuralFeature(lastCursor);
944     }
945     
946     public Object JavaDoc next()
947     {
948       return ((Entry)super.next()).getValue();
949     }
950     
951     public Object JavaDoc previous()
952     {
953       return ((Entry)super.next()).getValue();
954     }
955
956     public void add(Object JavaDoc value)
957     {
958       super.add(FeatureMapUtil.createEntry(feature(), value));
959     }
960     
961     public void add(EStructuralFeature eStructuralFeature, Object JavaDoc value)
962     {
963       super.add(FeatureMapUtil.createEntry(eStructuralFeature, value));
964     }
965   }
966
967 /*
968   public List subList(EStructuralFeature feature, int from, int to)
969   {
970     return null;
971   }
972 */

973
974   public EList list(EStructuralFeature feature)
975   {
976     return
977       FeatureMapUtil.isFeatureMap(feature) ?
978         new FeatureMapUtil.FeatureFeatureMap(feature, this) :
979         new FeatureMapUtil.FeatureEList(feature, this);
980   }
981
982   public EStructuralFeature.Setting setting(EStructuralFeature feature)
983   {
984     return
985       isMany(feature) ?
986         (EStructuralFeature.Setting)list(feature) :
987         (EStructuralFeature.Setting)new FeatureMapUtil.FeatureValue(feature, this);
988   }
989
990   public List JavaDoc basicList(EStructuralFeature feature)
991   {
992     return new FeatureMapUtil.FeatureEList.Basic(feature, this);
993   }
994
995   public Iterator JavaDoc basicIterator(EStructuralFeature feature)
996   {
997     return new FeatureEIterator(feature, this);
998   }
999
1000  public ListIterator JavaDoc basicListIterator(EStructuralFeature feature)
1001  {
1002    return new FeatureEIterator(feature, this);
1003  }
1004
1005  public ListIterator JavaDoc basicListIterator(EStructuralFeature feature, int index)
1006  {
1007    ListIterator JavaDoc result = new FeatureEIterator(feature, this);
1008    for (int i = 0; i < index; ++i)
1009    {
1010      result.next();
1011    }
1012    return result;
1013  }
1014
1015  public Object JavaDoc[] toArray(EStructuralFeature feature)
1016  {
1017    List JavaDoc result = new BasicEList();
1018    FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
1019    if (FeatureMapUtil.isFeatureMap(feature))
1020    {
1021      for (int i = 0, size = delegateSize(); i < size; ++i)
1022      {
1023        Entry entry = (Entry)delegateGet(i);
1024        if (validator.isValid(entry.getEStructuralFeature()))
1025        {
1026          result.add(entry);
1027        }
1028      }
1029    }
1030    else
1031    {
1032      for (int i = 0, size = delegateSize(); i < size; ++i)
1033      {
1034        Entry entry = (Entry)delegateGet(i);
1035        if (validator.isValid(entry.getEStructuralFeature()))
1036        {
1037          result.add(entry.getValue());
1038        }
1039      }
1040    }
1041    return result.toArray();
1042  }
1043
1044  public Object JavaDoc[] toArray(EStructuralFeature feature, Object JavaDoc [] array)
1045  {
1046    List JavaDoc result = new BasicEList();
1047    FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
1048    if (FeatureMapUtil.isFeatureMap(feature))
1049    {
1050      for (int i = 0, size = delegateSize(); i < size; ++i)
1051      {
1052        Entry entry = (Entry)delegateGet(i);
1053        if (validator.isValid(entry.getEStructuralFeature()))
1054        {
1055          result.add(entry);
1056        }
1057      }
1058    }
1059    else
1060    {
1061      for (int i = 0, size = delegateSize(); i < size; ++i)
1062      {
1063        Entry entry = (Entry)delegateGet(i);
1064        if (validator.isValid(entry.getEStructuralFeature()))
1065        {
1066          result.add(entry.getValue());
1067        }
1068      }
1069    }
1070    return result.toArray(array);
1071  }
1072
1073
1074  public void set(EStructuralFeature feature, Object JavaDoc object)
1075  {
1076    if (isMany(feature))
1077    {
1078      List JavaDoc list = list(feature);
1079      list.clear();
1080      list.addAll((Collection JavaDoc)object);
1081    }
1082    else
1083    {
1084      FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
1085      for (int i = 0, size = delegateSize(); i < size; ++i)
1086      {
1087        Entry entry = (Entry)delegateGet(i);
1088        if (validator.isValid(entry.getEStructuralFeature()))
1089        {
1090          if (shouldUnset(feature, object))
1091          {
1092            remove(i);
1093          }
1094          else
1095          {
1096            doSet(i, FeatureMapUtil.isFeatureMap(feature) ? (Entry)object : createEntry(feature, object));
1097          }
1098          return;
1099        }
1100      }
1101  
1102      if (!shouldUnset(feature, object))
1103      {
1104        doAdd(FeatureMapUtil.isFeatureMap(feature) ? (Entry)object : createEntry(feature, object));
1105      }
1106    }
1107  }
1108
1109  protected boolean shouldUnset(EStructuralFeature feature, Object JavaDoc value)
1110  {
1111    if (feature.getUpperBound() != EStructuralFeature.UNSPECIFIED_MULTIPLICITY && !feature.isUnsettable())
1112    {
1113      Object JavaDoc defaultValue = feature.getDefaultValue();
1114      return defaultValue == null ? value == null : defaultValue.equals(value);
1115    }
1116    else
1117    {
1118      return false;
1119    }
1120  }
1121
1122  public void add(int index, EStructuralFeature feature, Object JavaDoc object)
1123  {
1124    boolean isFeatureMap = FeatureMapUtil.isFeatureMap(feature);
1125    if (isMany(feature))
1126    {
1127      if (feature.isUnique() && contains(feature, object))
1128      {
1129        throw new IllegalArgumentException JavaDoc("The 'no duplicates' constraint is violated");
1130      }
1131    }
1132    else
1133    {
1134      FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
1135      for (int i = 0, size = delegateSize(); i < size; ++i)
1136      {
1137        Entry entry = (Entry)delegateGet(i);
1138        if (validator.isValid(entry.getEStructuralFeature()))
1139        {
1140          if (isFeatureMap ? entry.equals(object) : object == null ? entry.getValue() == null : object.equals(entry.getValue()))
1141          {
1142            throw new IllegalArgumentException JavaDoc("The 'no duplicates' constraint is violated");
1143          }
1144        }
1145      }
1146    }
1147
1148    doAdd(index, isFeatureMap ? (Entry)object : createEntry(feature, object));
1149  }
1150
1151  public boolean add(EStructuralFeature feature, Object JavaDoc object)
1152  {
1153    boolean isFeatureMap = FeatureMapUtil.isFeatureMap(feature);
1154    if (isMany(feature))
1155    {
1156      if (feature.isUnique() && contains(feature, object))
1157      {
1158        return false;
1159      }
1160    }
1161    else
1162    {
1163      FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
1164      for (int i = 0, size = delegateSize(); i < size; ++i)
1165      {
1166        Entry entry = (Entry)delegateGet(i);
1167        if (validator.isValid(entry.getEStructuralFeature()))
1168        {
1169          if (isFeatureMap ? entry.equals(object) : object == null ? entry.getValue() == null : object.equals(entry.getValue()))
1170          {
1171            return false;
1172          }
1173          else
1174          {
1175            doSet(i, isFeatureMap ? (Entry)object : createEntry(feature, object));
1176            return true;
1177          }
1178        }
1179      }
1180    }
1181
1182    return doAdd(isFeatureMap ? (Entry)object : createEntry(feature, object));
1183  }
1184
1185  public void add(EStructuralFeature feature, int index, Object JavaDoc object)
1186  {
1187    boolean isFeatureMap = FeatureMapUtil.isFeatureMap(feature);
1188    if (isMany(feature))
1189    {
1190      if (feature.isUnique() && contains(feature, object))
1191      {
1192        throw new IllegalArgumentException JavaDoc("The 'no duplicates' constraint is violated");
1193      }
1194    }
1195    else
1196    {
1197      FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
1198      for (int i = 0, size = delegateSize(); i < size; ++i)
1199      {
1200        Entry entry = (Entry)delegateGet(i);
1201        if (validator.isValid(entry.getEStructuralFeature()))
1202        {
1203          throw new IllegalArgumentException JavaDoc("The multiplicity constraint is violated");
1204        }
1205      }
1206    }
1207
1208    doAdd(entryIndex(feature, index), isFeatureMap ? (Entry)object : createEntry(feature, object));
1209  }
1210
1211  public boolean addAll(int index, EStructuralFeature feature, Collection JavaDoc collection)
1212  {
1213    if (collection.size() == 0)
1214    {
1215      return false;
1216    }
1217    boolean isFeatureMap = FeatureMapUtil.isFeatureMap(feature);
1218    Collection JavaDoc entryCollection = isFeatureMap ? collection : new BasicEList(collection.size());
1219    if (isMany(feature))
1220    {
1221      if (feature.isUnique())
1222      {
1223        for (Iterator JavaDoc i = collection.iterator(); i.hasNext(); )
1224        {
1225          Object JavaDoc object = i.next();
1226          if (!contains(feature, object))
1227          {
1228            Entry entry = createEntry(feature, object);
1229            if (!entryCollection.contains(entry))
1230            {
1231              entryCollection.add(entry);
1232            }
1233          }
1234        }
1235      }
1236      else if (!isFeatureMap)
1237      {
1238        for (Iterator JavaDoc i = collection.iterator(); i.hasNext(); )
1239        {
1240          Entry entry = createEntry(feature, i.next());
1241          entryCollection.add(entry);
1242        }
1243      }
1244    }
1245    else
1246    {
1247      if (collection.size() > 1)
1248      {
1249        throw new IllegalArgumentException JavaDoc("The multiplicity constraint is violated");
1250      }
1251
1252      if (isFeatureMap)
1253      {
1254        if (contains(feature, collection.iterator().next()))
1255        {
1256          return false;
1257        }
1258      }
1259      else
1260      {
1261        FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
1262        for (int i = 0, size = delegateSize(); i < size; ++i)
1263        {
1264          Entry entry = (Entry)delegateGet(i);
1265          if (validator.isValid(entry.getEStructuralFeature()))
1266          {
1267            if (collection.contains(entry.getValue()))
1268            {
1269              return false;
1270            }
1271            else
1272            {
1273              throw new IllegalArgumentException JavaDoc("The multiplicity constraint is violated");
1274            }
1275          }
1276        }
1277        Entry entry = createEntry(feature, collection.iterator().next());
1278        entryCollection.add(entry);
1279      }
1280    }
1281
1282    return doAddAll(index, entryCollection);
1283  }
1284
1285  public boolean addAll(EStructuralFeature feature, Collection JavaDoc collection)
1286  {
1287    if (collection.size() == 0)
1288    {
1289      return false;
1290    }
1291    boolean isFeatureMap = FeatureMapUtil.isFeatureMap(feature);
1292    Collection JavaDoc entryCollection = isFeatureMap ? collection : new BasicEList(collection.size());
1293    if (isMany(feature))
1294    {
1295      if (feature.isUnique())
1296      {
1297        for (Iterator JavaDoc i = collection.iterator(); i.hasNext(); )
1298        {
1299          Object JavaDoc object = i.next();
1300          if (!contains(feature, object))
1301          {
1302            Entry entry = createEntry(feature, object);
1303            if (!entryCollection.contains(entry))
1304            {
1305              entryCollection.add(entry);
1306            }
1307          }
1308        }
1309      }
1310      else if (!isFeatureMap)
1311      {
1312        for (Iterator JavaDoc i = collection.iterator(); i.hasNext(); )
1313        {
1314          Entry entry = createEntry(feature, i.next());
1315          entryCollection.add(entry);
1316        }
1317      }
1318    }
1319    else
1320    {
1321      if (collection.size() > 1)
1322      {
1323        throw new IllegalArgumentException JavaDoc("The multiplicity constraint is violated");
1324      }
1325      FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
1326      for (int i = 0, size = delegateSize(); i < size; ++i)
1327      {
1328        Entry entry = (Entry)delegateGet(i);
1329        if (validator.isValid(entry.getEStructuralFeature()))
1330        {
1331          if (collection.contains(isFeatureMap ? entry : entry.getValue()))
1332          {
1333            return false;
1334          }
1335          else
1336          {
1337            for (Iterator JavaDoc j = collection.iterator(); j.hasNext(); )
1338            {
1339              doSet(i, isFeatureMap ? j.next() : createEntry(feature, j.next()));
1340            }
1341            return true;
1342          }
1343        }
1344      }
1345      if (!isFeatureMap)
1346      {
1347        Entry entry = createEntry(feature, collection.iterator().next());
1348        entryCollection.add(entry);
1349      }
1350    }
1351
1352    return doAddAll(entryCollection);
1353  }
1354
1355  public boolean addAll(EStructuralFeature feature, int index, Collection JavaDoc collection)
1356  {
1357    if (collection.size() == 0)
1358    {
1359      return false;
1360    }
1361    boolean isFeatureMap = FeatureMapUtil.isFeatureMap(feature);
1362    Collection JavaDoc entryCollection = isFeatureMap ? collection : new BasicEList(collection.size());
1363    if (isMany(feature))
1364    {
1365      if (feature.isUnique())
1366      {
1367        for (Iterator JavaDoc i = collection.iterator(); i.hasNext(); )
1368        {
1369          Object JavaDoc object = i.next();
1370          if (!contains(feature, object))
1371          {
1372            Entry entry = createEntry(feature, object);
1373            entryCollection.add(entry);
1374          }
1375        }
1376      }
1377      else if (!isFeatureMap)
1378      {
1379        for (Iterator JavaDoc i = collection.iterator(); i.hasNext(); )
1380        {
1381          Entry entry = createEntry(feature, i.next());
1382          entryCollection.add(entry);
1383        }
1384      }
1385    }
1386    else
1387    {
1388      FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
1389      for (int i = 0, size = delegateSize(); i < size; ++i)
1390      {
1391        Entry entry = (Entry)delegateGet(i);
1392        if (validator.isValid(entry.getEStructuralFeature()))
1393        {
1394          throw new IllegalArgumentException JavaDoc("The multiplicity constraint is violated");
1395        }
1396      }
1397
1398      if (collection.size() > 1)
1399      {
1400        throw new IllegalArgumentException JavaDoc("The multiplicity constraint is violated");
1401      }
1402
1403      if (!isFeatureMap)
1404      {
1405        Entry entry = createEntry(feature, collection.iterator().next());
1406        entryCollection.add(entry);
1407      }
1408    }
1409
1410    return doAddAll(entryIndex(feature, index), entryCollection);
1411  }
1412
1413  public void addUnique(EStructuralFeature feature, Object JavaDoc object)
1414  {
1415    addUnique(createEntry(feature, object));
1416  }
1417
1418  public void addUnique(EStructuralFeature feature, int index, Object JavaDoc object)
1419  {
1420    addUnique(entryIndex(feature, index), createEntry(feature, object));
1421  }
1422
1423  public NotificationChain basicAdd(EStructuralFeature feature, Object JavaDoc object, NotificationChain notifications)
1424  {
1425    if (object == null)
1426    {
1427      for (int i = 0, size = delegateSize(); i < size; ++i)
1428      {
1429        Entry entry = (Entry)delegateGet(i);
1430        if (entry.getEStructuralFeature() == feature)
1431        {
1432          return super.basicRemove(entry, notifications);
1433        }
1434      }
1435    }
1436
1437    Entry entry = FeatureMapUtil.isFeatureMap(feature) ? (Entry)object : createEntry(feature, object);
1438
1439    notifications = basicAdd(entry, notifications);
1440    if (isNotificationRequired())
1441    {
1442      boolean oldIsSet = !isEmpty(feature);
1443      NotificationImpl notification =
1444        feature.isMany() ?
1445          createNotification
1446            (Notification.ADD,
1447             feature,
1448             null,
1449             object,
1450             indexOf(feature, object),
1451             oldIsSet) :
1452          createNotification
1453            (Notification.SET,
1454             feature,
1455             feature.getDefaultValue(),
1456             object,
1457             Notification.NO_INDEX,
1458             oldIsSet);
1459
1460      if (notifications != null)
1461      {
1462        notifications.add(notification);
1463      }
1464      else
1465      {
1466        notifications = notification;
1467      }
1468    }
1469    return notifications;
1470  }
1471
1472  public boolean remove(EStructuralFeature feature, Object JavaDoc object)
1473  {
1474    FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
1475    if (FeatureMapUtil.isFeatureMap(feature))
1476    {
1477      for (int i = 0, size = delegateSize(); i < size; ++i)
1478      {
1479        Entry entry = (Entry)delegateGet(i);
1480        if (validator.isValid(entry.getEStructuralFeature()))
1481        {
1482          if (entry.equals(object))
1483          {
1484            remove(i);
1485            return true;
1486          }
1487        }
1488      }
1489    }
1490    else if (object != null)
1491    {
1492      for (int i = 0, size = delegateSize(); i < size; ++i)
1493      {
1494        Entry entry = (Entry)delegateGet(i);
1495        if (validator.isValid(entry.getEStructuralFeature()))
1496        {
1497          if (object.equals(entry.getValue()))
1498          {
1499            remove(i);
1500            return true;
1501          }
1502        }
1503      }
1504    }
1505    else
1506    {
1507      for (int i = 0, size = delegateSize(); i < size; ++i)
1508      {
1509        Entry entry = (Entry)delegateGet(i);
1510        if (validator.isValid(entry.getEStructuralFeature()))
1511        {
1512          if (entry.getValue() == null)
1513          {
1514            remove(i);
1515            return true;
1516          }
1517        }
1518      }
1519    }
1520
1521    return false;
1522  }
1523
1524  public Object JavaDoc remove(EStructuralFeature feature, int index)
1525  {
1526    FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
1527    int count = 0;
1528    for (int i = 0, size = delegateSize(); i < size; ++i)
1529    {
1530      Entry entry = (Entry)delegateGet(i);
1531      if (validator.isValid(entry.getEStructuralFeature()))
1532      {
1533        if (count == index)
1534        {
1535          remove(i);
1536          return FeatureMapUtil.isFeatureMap(feature) ? entry : entry.getValue();
1537        }
1538        ++count;
1539      }
1540    }
1541
1542    throw new IndexOutOfBoundsException JavaDoc("index=" + index + ", size=" + count);
1543  }
1544
1545  public boolean removeAll(EStructuralFeature feature, Collection JavaDoc collection)
1546  {
1547    if (FeatureMapUtil.isFeatureMap(feature))
1548    {
1549      return removeAll(collection);
1550    }
1551    else
1552    {
1553      FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
1554      List JavaDoc entryCollection = new BasicEList(collection.size());
1555      for (int i = delegateSize(); --i >= 0; )
1556      {
1557        Entry entry = (Entry)delegateGet(i);
1558        if (validator.isValid(entry.getEStructuralFeature()))
1559        {
1560          if (collection.contains(entry.getValue()))
1561          {
1562            entryCollection.add(entry);
1563          }
1564        }
1565      }
1566
1567      return removeAll(entryCollection);
1568    }
1569  }
1570
1571  public NotificationChain basicRemove(EStructuralFeature feature, Object JavaDoc object, NotificationChain notifications)
1572  {
1573    FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
1574    int count = 0;
1575    Entry match = null;
1576    if (FeatureMapUtil.isFeatureMap(feature))
1577    {
1578      for (int i = 0, size = delegateSize(); i < size; ++i)
1579      {
1580        Entry entry = (Entry)delegateGet(i);
1581        if (validator.isValid(entry.getEStructuralFeature()))
1582        {
1583          if (entry.equals(object))
1584          {
1585            match = entry;
1586            break;
1587          }
1588          ++count;
1589        }
1590      }
1591    }
1592    if (object != null)
1593    {
1594      for (int i = 0, size = delegateSize(); i < size; ++i)
1595      {
1596        Entry entry = (Entry)delegateGet(i);
1597        if (validator.isValid(entry.getEStructuralFeature()))
1598        {
1599          if (object.equals(entry.getValue()))
1600          {
1601            match = entry;
1602            break;
1603          }
1604          ++count;
1605        }
1606      }
1607    }
1608    else
1609    {
1610      for (int i = 0, size = delegateSize(); i < size; ++i)
1611      {
1612        Entry entry = (Entry)delegateGet(i);
1613        if (validator.isValid(entry.getEStructuralFeature()))
1614        {
1615          if (entry.getValue() == null)
1616          {
1617            match = entry;
1618            break;
1619          }
1620          ++count;
1621        }
1622      }
1623    }
1624
1625    if (match != null)
1626    {
1627      if (isNotificationRequired())
1628      {
1629        NotificationImpl notification =
1630          feature.isMany() ?
1631            createNotification
1632              (Notification.REMOVE,
1633               feature,
1634               object,
1635               null,
1636               count,
1637               true) :
1638            createNotification
1639              (feature.isUnsettable() ? Notification.UNSET : Notification.SET,
1640               feature,
1641               object,
1642               feature.getDefaultValue(),
1643               Notification.NO_INDEX,
1644               true);
1645  
1646        if (notifications != null)
1647        {
1648          notifications.add(notification);
1649        }
1650        else
1651        {
1652          notifications = notification;
1653        }
1654      }
1655      notifications = basicRemove(match, notifications);
1656    }
1657
1658    return notifications;
1659  }
1660
1661  public boolean retainAll(EStructuralFeature feature, Collection JavaDoc collection)
1662  {
1663    boolean isFeatureMap = FeatureMapUtil.isFeatureMap(feature);
1664    FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
1665    List JavaDoc entryCollection = new BasicEList(collection.size());
1666    for (int i = delegateSize(); --i >= 0; )
1667    {
1668      Entry entry = (Entry)delegateGet(i);
1669      if (validator.isValid(entry.getEStructuralFeature()))
1670      {
1671        if (!collection.contains(isFeatureMap ? entry : entry.getValue()))
1672        {
1673          entryCollection.add(entry);
1674        }
1675      }
1676    }
1677
1678    return removeAll(entryCollection);
1679  }
1680
1681  public void clear(EStructuralFeature feature)
1682  {
1683    FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
1684    List JavaDoc entryCollection = new BasicEList();
1685    for (int i = delegateSize(); --i >= 0; )
1686    {
1687      Entry entry = (Entry)delegateGet(i);
1688      if (validator.isValid(entry.getEStructuralFeature()))
1689      {
1690        entryCollection.add(entry);
1691      }
1692    }
1693
1694    if (!removeAll(entryCollection))
1695    {
1696      dispatchNotification
1697        (feature.isMany() ?
1698           createNotification
1699             (Notification.REMOVE_MANY,
1700              feature,
1701              Collections.EMPTY_LIST,
1702              null,
1703              Notification.NO_INDEX,
1704              false) :
1705           createNotification
1706             (feature.isUnsettable() ? Notification.UNSET : Notification.SET,
1707              feature,
1708              null,
1709              null,
1710              Notification.NO_INDEX,
1711              false));
1712    }
1713  }
1714
1715  public void move(EStructuralFeature feature, int index, Object JavaDoc object)
1716  {
1717    move(feature, index, indexOf(feature, object));
1718  }
1719
1720  public Object JavaDoc move(EStructuralFeature feature, int targetIndex, int sourceIndex)
1721  {
1722    if (isMany(feature))
1723    {
1724      FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
1725      Object JavaDoc result = null;
1726      int entryTargetIndex = -1;
1727      int entrySourceIndex = -1;
1728      int count = 0;
1729      for (int i = 0, size = delegateSize(); i < size; ++i)
1730      {
1731        Entry entry = (Entry)delegateGet(i);
1732        if (validator.isValid(entry.getEStructuralFeature()))
1733        {
1734          if (count == targetIndex)
1735          {
1736            entryTargetIndex = i;
1737          }
1738          if (count == sourceIndex)
1739          {
1740            entrySourceIndex = i;
1741            result = entry.getValue();
1742          }
1743          ++count;
1744        }
1745      }
1746      if (entryTargetIndex == -1)
1747      {
1748        throw new IndexOutOfBoundsException JavaDoc("targetIndex=" + targetIndex + ", size=" + count);
1749      }
1750      if (entrySourceIndex == -1)
1751      {
1752        throw new IndexOutOfBoundsException JavaDoc("sourceIndex=" + targetIndex + ", size=" + count);
1753      }
1754
1755      doMove(entryTargetIndex, entrySourceIndex);
1756
1757      if (isNotificationRequired())
1758      {
1759        dispatchNotification
1760          (createNotification
1761             (Notification.MOVE,
1762              feature,
1763              new Integer JavaDoc(sourceIndex),
1764              result,
1765              targetIndex,
1766              true));
1767      }
1768
1769      return result;
1770    }
1771    else
1772    {
1773      throw new IllegalArgumentException JavaDoc("The feature must be many-valued to support move");
1774    }
1775  }
1776
1777  public Object JavaDoc get(EStructuralFeature feature, boolean resolve)
1778  {
1779    if (isMany(feature))
1780    {
1781      return list(feature);
1782    }
1783    else
1784    {
1785      FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
1786      int count = 0;
1787      for (int i = 0, size = delegateSize(); i < size; ++i)
1788      {
1789        Entry entry = (Entry)delegateGet(i);
1790        if (validator.isValid(entry.getEStructuralFeature()))
1791        {
1792          if (FeatureMapUtil.isFeatureMap(feature))
1793          {
1794            return entry;
1795          }
1796          else
1797          {
1798            Object JavaDoc value = entry.getValue();
1799            if (value != null && resolve && isResolveProxies(feature))
1800            {
1801              value = resolveProxy(feature, i, count, value);
1802            }
1803            return value;
1804          }
1805        }
1806        ++count;
1807      }
1808
1809      return feature.getDefaultValue();
1810    }
1811  }
1812
1813  public Object JavaDoc get(EStructuralFeature feature, int index, boolean resolve)
1814  {
1815    FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
1816    if (isMany(feature))
1817    {
1818      int count = 0;
1819      for (int i = 0, size = delegateSize(); i < size; ++i)
1820      {
1821        Entry entry = (Entry)delegateGet(i);
1822        if (validator.isValid(entry.getEStructuralFeature()))
1823        {
1824          if (count == index)
1825          {
1826            if (FeatureMapUtil.isFeatureMap(feature))
1827            {
1828              return entry;
1829            }
1830            else
1831            {
1832              Object JavaDoc value = entry.getValue();
1833              if (value != null && resolve && isResolveProxies(feature))
1834              {
1835                value = resolveProxy(feature, i, count, entry.getValue());
1836              }
1837              return value;
1838            }
1839          }
1840          ++count;
1841        }
1842      }
1843      throw new IndexOutOfBoundsException JavaDoc("index=" + index + ", size=" + count);
1844    }
1845    else
1846    {
1847      int count = 0;
1848      for (int i = 0, size = delegateSize(); i < size; ++i)
1849      {
1850        Entry entry = (Entry)delegateGet(i);
1851        if (validator.isValid(entry.getEStructuralFeature()))
1852        {
1853          if (FeatureMapUtil.isFeatureMap(feature))
1854          {
1855            return entry;
1856          }
1857          else
1858          {
1859            Object JavaDoc value = entry.getValue();
1860            if (value != null && resolve && isResolveProxies(feature))
1861            {
1862              value = resolveProxy(feature, i, count, value);
1863            }
1864            return value;
1865          }
1866        }
1867        ++count;
1868      }
1869
1870      return feature.getDefaultValue();
1871    }
1872  }
1873
1874  public Object JavaDoc set(EStructuralFeature feature, int index, Object JavaDoc object)
1875  {
1876    FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
1877    if (isMany(feature))
1878    {
1879      if (feature.isUnique())
1880      {
1881        int currentIndex = indexOf(feature, object);
1882        if (currentIndex >=0 && currentIndex != index)
1883        {
1884          throw new IllegalArgumentException JavaDoc("The 'no duplicates' constraint is violated");
1885        }
1886      }
1887
1888      int count = 0;
1889      for (int i = 0, size = delegateSize(); i < size; ++i)
1890      {
1891        Entry entry = (Entry)delegateGet(i);
1892        if (validator.isValid(entry.getEStructuralFeature()))
1893        {
1894          if (count == index)
1895          {
1896            return doSet(i, FeatureMapUtil.isFeatureMap(feature) ? object : createEntry(feature, object));
1897          }
1898          ++count;
1899        }
1900      }
1901      throw new IndexOutOfBoundsException JavaDoc("index=" + index + ", size=" + count);
1902    }
1903    else
1904    {
1905      // Index should be -1.
1906

1907      for (int i = 0, size = delegateSize(); i < size; ++i)
1908      {
1909        Entry entry = (Entry)delegateGet(i);
1910        if (validator.isValid(entry.getEStructuralFeature()))
1911        {
1912          return FeatureMapUtil.isFeatureMap(feature) ? entry : entry.getValue();
1913        }
1914      }
1915
1916      return null;
1917    }
1918  }
1919
1920  public Object JavaDoc setUnique(EStructuralFeature feature, int index, Object JavaDoc object)
1921  {
1922    FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
1923    if (isMany(feature))
1924    {
1925      int count = 0;
1926      for (int i = 0, size = delegateSize(); i < size; ++i)
1927      {
1928        Entry entry = (Entry)delegateGet(i);
1929        if (validator.isValid(entry.getEStructuralFeature()))
1930        {
1931          if (count == index)
1932          {
1933            return setUnique(i, FeatureMapUtil.isFeatureMap(feature) ? object : createEntry(feature, object));
1934          }
1935          ++count;
1936        }
1937      }
1938      throw new IndexOutOfBoundsException JavaDoc("index=" + index + ", size=" + count);
1939    }
1940    else
1941    {
1942      // Index should be -1.
1943

1944      for (int i = 0, size = delegateSize(); i < size; ++i)
1945      {
1946        Entry entry = (Entry)delegateGet(i);
1947        if (validator.isValid(entry.getEStructuralFeature()))
1948        {
1949          return setUnique(i, FeatureMapUtil.isFeatureMap(feature) ? object : createEntry(feature, object));
1950        }
1951      }
1952
1953      return feature.getDefaultValue();
1954    }
1955  }
1956
1957  public boolean isSet(EStructuralFeature feature)
1958  {
1959    return !isEmpty(feature);
1960  }
1961
1962  public void unset(EStructuralFeature feature)
1963  {
1964    FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
1965    List JavaDoc removals = null;
1966    for (int i = 0, size = delegateSize(); i < size; ++i)
1967    {
1968      Entry entry = (Entry)delegateGet(i);
1969      if (validator.isValid(entry.getEStructuralFeature()))
1970      {
1971        if (removals == null)
1972        {
1973          removals = new BasicEList();
1974        }
1975        removals.add(entry);
1976      }
1977    }
1978
1979    if (removals != null)
1980    {
1981      removeAll(removals);
1982    }
1983  }
1984
1985  public NotificationChain basicRemove(Object JavaDoc object, NotificationChain notifications)
1986  {
1987    // This may be called directly on an EObject for the case of a containment.
1988
//
1989
if (object instanceof FeatureMap.Entry)
1990    {
1991      return super.basicRemove(object, notifications);
1992    }
1993    else
1994    {
1995      Entry match = null;
1996      EStructuralFeature feature = null;
1997      for (int i = 0, size = delegateSize(); i < size; ++i)
1998      {
1999        Entry entry = (Entry)delegateGet(i);
2000        if (object.equals(entry.getValue()))
2001        {
2002          feature = entry.getEStructuralFeature();
2003          if (feature instanceof EReference && ((EReference)feature).isContainment())
2004          {
2005            match = entry;
2006            break;
2007          }
2008        }
2009      }
2010
2011      if (match != null)
2012      {
2013        if (isNotificationRequired())
2014        {
2015          NotificationImpl notification =
2016            feature.isMany() ?
2017              createNotification
2018                (Notification.REMOVE,
2019                 feature,
2020                 object,
2021                 null,
2022                 indexOf(feature, object),
2023                 true) :
2024              createNotification
2025                (feature.isUnsettable() ? Notification.UNSET : Notification.SET,
2026                 feature,
2027                 object,
2028                 feature.getDefaultValue(),
2029                 Notification.NO_INDEX,
2030                 true);
2031
2032          if (notifications != null)
2033          {
2034            notifications.add(notification);
2035          }
2036          else
2037          {
2038            notifications = notification;
2039          }
2040        }
2041        notifications = basicRemove(match, notifications);
2042      }
2043
2044      return notifications;
2045    }
2046  }
2047
2048  /**
2049   * -------------------------------------------
2050   */

2051  public static class FeatureEIterator extends FeatureMapUtil.BasicFeatureEIterator
2052  {
2053    public FeatureEIterator(EStructuralFeature eStructuralFeature, FeatureMap.Internal featureMap)
2054    {
2055      super(eStructuralFeature, featureMap);
2056    }
2057
2058    protected boolean scanNext()
2059    {
2060      int size = featureMap.size();
2061      while (entryCursor < size)
2062      {
2063        Entry entry = (Entry)featureMap.get(entryCursor);
2064        if (validator.isValid(entry.getEStructuralFeature()))
2065        {
2066          preparedResult = extractValue(entry);
2067          prepared = 2;
2068          return true;
2069        }
2070        ++entryCursor;
2071      }
2072
2073      prepared = 1;
2074      lastCursor = -1;
2075      return false;
2076    }
2077
2078    protected boolean scanPrevious()
2079    {
2080      while (--entryCursor >= 0)
2081      {
2082        Entry entry = (Entry)featureMap.get(entryCursor);
2083        if (validator.isValid(entry.getEStructuralFeature()))
2084        {
2085          preparedResult = extractValue(entry);
2086          prepared = -2;
2087          return true;
2088        }
2089      }
2090
2091      prepared = -1;
2092      lastCursor = -1;
2093      return false;
2094    }
2095  }
2096
2097  /**
2098   * -------------------------------------------
2099   */

2100  public static class ResolvingFeatureEIterator extends FeatureEIterator
2101  {
2102    public ResolvingFeatureEIterator(EStructuralFeature eStructuralFeature, FeatureMap.Internal featureMap)
2103    {
2104      super(eStructuralFeature, featureMap);
2105    }
2106
2107    protected boolean resolve()
2108    {
2109      return true;
2110    }
2111  }
2112
2113  /**
2114   * Temporary for testing purposes only.
2115   */

2116  public static class FeatureMapEObjectImpl extends org.eclipse.emf.ecore.impl.EObjectImpl
2117  {
2118    protected DelegatingFeatureMap featureMap =
2119      new DelegatingFeatureMap(this, -1)
2120      {
2121        protected List JavaDoc theList = new java.util.ArrayList JavaDoc();
2122        protected List JavaDoc delegateList()
2123        {
2124          return theList;
2125        }
2126      };
2127
2128
2129    public FeatureMapEObjectImpl()
2130    {
2131      super();
2132    }
2133
2134    public Object JavaDoc eDynamicGet(EStructuralFeature eFeature, boolean resolve)
2135    {
2136      if (eFeature instanceof EReference && ((EReference)eFeature).isContainer())
2137      {
2138        return eSettingDelegate(eFeature).dynamicGet(this, null, -1, true);
2139      }
2140      else
2141      {
2142        return featureMap.setting(eFeature).get(resolve);
2143      }
2144    }
2145
2146    public void eDynamicSet(EStructuralFeature eFeature, Object JavaDoc newValue)
2147    {
2148      if (eFeature instanceof EReference && ((EReference)eFeature).isContainer())
2149      {
2150        eSettingDelegate(eFeature).dynamicSet(this, null, -1, newValue);
2151      }
2152      else
2153      {
2154        if (!eFeature.isUnsettable())
2155        {
2156          Object JavaDoc defaultValue = eFeature.getDefaultValue();
2157          if (defaultValue == null ? newValue == null : defaultValue.equals(newValue))
2158          {
2159            featureMap.setting(eFeature).unset();
2160            return;
2161          }
2162        }
2163        featureMap.setting(eFeature).set(newValue);
2164      }
2165
2166/*
2167      if (eFeature instanceof EReference)
2168      {
2169        EReference eReference = (EReference)eFeature;
2170        EReference eOpposite = ((EReference)eFeature).getEOpposite();
2171        if (eOpposite != null)
2172        {
2173          if (!eReference.isContainment() && !eReference.isMany() && !eOpposite.isMany() && !eOpposite.isContainment())
2174          {
2175            if (eDynamicGet(eFeature, false) != newValue)
2176            {
2177              //Thread.dumpStack();
2178            }
2179            else if (newValue instanceof EObject && ((EObject)newValue).eGet(eOpposite) != this)
2180            {
2181              Thread.dumpStack();
2182            }
2183          }
2184        }
2185      }
2186*/

2187    }
2188
2189    public void eDynamicUnset(EStructuralFeature eFeature)
2190    {
2191      if (eFeature instanceof EReference && ((EReference)eFeature).isContainer())
2192      {
2193        eSettingDelegate(eFeature).dynamicUnset(this, null, -1);
2194      }
2195      else
2196      {
2197        featureMap.setting(eFeature).unset();
2198      }
2199    }
2200
2201    public boolean eDynamicIsSet(EStructuralFeature eFeature)
2202    {
2203      if (eFeature instanceof EReference && ((EReference)eFeature).isContainer())
2204      {
2205        return eSettingDelegate(eFeature).dynamicIsSet(this, null, -1);
2206      }
2207      else
2208      {
2209        return featureMap.setting(eFeature).isSet();
2210      }
2211    }
2212
2213    public NotificationChain eDynamicInverseAdd(InternalEObject otherEnd, int featureID, Class JavaDoc inverseClass, NotificationChain notifications)
2214    {
2215      EStructuralFeature.Internal feature = (EStructuralFeature.Internal)eClass().getEStructuralFeature(featureID);
2216      if (feature.isMany())
2217      {
2218        return featureMap.basicAdd(feature, otherEnd, notifications);
2219      }
2220      else if (feature instanceof EReference && ((EReference)feature).isContainer())
2221      {
2222        return eSettingDelegate(feature).dynamicInverseAdd(this, null, -1, otherEnd, notifications);
2223      }
2224      else
2225      {
2226        InternalEObject oldValue = (InternalEObject)eDynamicGet(feature, false);
2227        if (oldValue != null)
2228        {
2229          notifications = oldValue.eInverseRemove
2230            (this, oldValue.eClass().getFeatureID(((EReference)feature).getEOpposite()), null, notifications);
2231          notifications = featureMap.basicRemove(feature, oldValue, notifications);
2232        }
2233
2234        return featureMap.basicAdd(feature, otherEnd, notifications);
2235      }
2236    }
2237
2238    public NotificationChain eDynamicInverseRemove(InternalEObject otherEnd, int featureID, Class JavaDoc inverseClass, NotificationChain notifications)
2239    {
2240      EStructuralFeature.Internal feature = (EStructuralFeature.Internal)eClass().getEStructuralFeature(featureID);
2241      if (feature instanceof EReference && ((EReference)feature).isContainer())
2242      {
2243        return eSettingDelegate(feature).dynamicInverseRemove(this, null, -1, otherEnd, notifications);
2244      }
2245      else
2246      {
2247        return featureMap.basicRemove(feature, otherEnd, notifications);
2248      }
2249    }
2250
2251    public FeatureMap featureMap()
2252    {
2253      return featureMap;
2254    }
2255
2256    public void eNotify(Notification notification)
2257    {
2258      if (notification.getFeatureID(null) != -1)
2259      {
2260        super.eNotify(notification);
2261      }
2262    }
2263
2264    public String JavaDoc toString()
2265    {
2266      String JavaDoc result = super.toString();
2267      result = "org.eclipse.emf.ecore.impl.EObjectImpl" + result.substring(result.indexOf("@"));
2268      return result;
2269    }
2270  }
2271}
2272
Popular Tags