KickJava   Java API By Example, From Geeks To Geeks.

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


1 /**
2  * <copyright>
3  *
4  * Copyright (c) 2002-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: EcoreEList.java,v 1.6 2005/06/08 06:20:10 nickb Exp $
16  */

17 package org.eclipse.emf.ecore.util;
18
19
20 import java.lang.reflect.Array JavaDoc;
21 import java.util.Iterator JavaDoc;
22 import java.util.List JavaDoc;
23 import java.util.ListIterator JavaDoc;
24
25 import org.eclipse.emf.common.notify.Notification;
26 import org.eclipse.emf.common.notify.NotificationChain;
27 import org.eclipse.emf.common.notify.impl.NotificationImpl;
28 import org.eclipse.emf.common.notify.impl.NotifyingListImpl;
29 import org.eclipse.emf.common.util.BasicEList;
30 import org.eclipse.emf.ecore.EClass;
31 import org.eclipse.emf.ecore.EClassifier;
32 import org.eclipse.emf.ecore.EEnum;
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 public class EcoreEList extends NotifyingListImpl implements InternalEList.Unsettable, EStructuralFeature.Setting
41 {
42   protected final Class JavaDoc dataClass;
43   protected final InternalEObject owner;
44
45   public EcoreEList(Class JavaDoc dataClass, InternalEObject owner)
46   {
47     super();
48     this.dataClass = dataClass;
49     this.owner = owner;
50   }
51
52   protected Object JavaDoc [] newData(int capacity)
53   {
54     return (Object JavaDoc [])Array.newInstance(dataClass, capacity);
55   }
56
57   protected Object JavaDoc validate(int index, Object JavaDoc object)
58   {
59     super.validate(index, object);
60     if (!hasInstanceClass() && object != null && !getFeatureType().isInstance(object))
61     {
62       throw new ArrayStoreException JavaDoc();
63     }
64     return object;
65   }
66
67   public Object JavaDoc getNotifier()
68   {
69     return owner;
70   }
71
72   public Object JavaDoc getFeature()
73   {
74     return getEStructuralFeature();
75   }
76
77   public int getFeatureID()
78   {
79     return getEStructuralFeature().getFeatureID();
80   }
81
82   public EStructuralFeature getEStructuralFeature()
83   {
84     return owner.eClass().getEStructuralFeature(getFeatureID());
85   }
86
87   protected EClassifier getFeatureType()
88   {
89     return getEStructuralFeature().getEType();
90   }
91
92   protected EReference getInverseEReference()
93   {
94     return ((EReference)getEStructuralFeature()).getEOpposite();
95   }
96
97   protected int getInverseFeatureID()
98   {
99     return getInverseEReference().getFeatureID();
100   }
101
102   protected Class JavaDoc getInverseFeatureClass()
103   {
104     return ((EClass)getInverseEReference().getEType()).getInstanceClass();
105   }
106
107   protected boolean hasManyInverse()
108   {
109     return false;
110   }
111
112   protected boolean hasNavigableInverse()
113   {
114     return false;
115   }
116
117   protected boolean isEObject()
118   {
119     return true;
120   }
121
122   protected boolean isContainment()
123   {
124     return false;
125   }
126
127   protected boolean hasProxies()
128   {
129     return false;
130   }
131
132   protected boolean hasInstanceClass()
133   {
134     return true;
135   }
136
137   protected Object JavaDoc resolve(int index, Object JavaDoc object)
138   {
139     return
140       isEObject() && hasProxies() ?
141         resolve(index, (EObject)object):
142         object;
143   }
144   
145   protected EObject resolve(int index, EObject eObject)
146   {
147     EObject resolved = resolveProxy(eObject);
148     if (resolved != eObject)
149     {
150       Object JavaDoc oldObject = data[index];
151       assign(index, validate(index, resolved));
152       didSet(index, resolved, oldObject);
153
154       if (isNotificationRequired())
155       {
156         owner.eNotify(createNotification(Notification.RESOLVE, eObject, resolved, index, false));
157       }
158
159       return resolved;
160     }
161     else
162     {
163       return eObject;
164     }
165   }
166
167   protected EObject resolveProxy(EObject eObject)
168   {
169     return eObject.eIsProxy() ? owner.eResolveProxy((InternalEObject)eObject) : eObject;
170   }
171
172   public Object JavaDoc[] toArray()
173   {
174     if (hasProxies())
175     {
176       for (int i = size - 1; i >= 0; --i)
177       {
178         get(i);
179       }
180     }
181     return super.toArray();
182   }
183
184   public Object JavaDoc[] toArray(Object JavaDoc array[])
185   {
186     if (hasProxies())
187     {
188       for (int i = size - 1; i >= 0; --i)
189       {
190         get(i);
191       }
192     }
193     return super.toArray(array);
194   }
195
196   protected NotificationImpl createNotification(int eventType, Object JavaDoc oldObject, Object JavaDoc newObject, int index, boolean wasSet)
197   {
198     return new ENotificationImpl(owner, eventType, getFeatureID(), oldObject, newObject, index, wasSet);
199   }
200
201   protected NotificationImpl createNotification(int eventType, boolean oldValue, boolean newValue)
202   {
203     return new ENotificationImpl(owner, eventType, getFeatureID(), oldValue, newValue);
204   }
205
206   /*
207    * Javadoc copied from base class.
208    */

209   protected void dispatchNotification(Notification notification)
210   {
211     owner.eNotify(notification);
212   }
213
214   public List JavaDoc basicList()
215   {
216     return super.basicList();
217   }
218
219   protected boolean isNotificationRequired()
220   {
221     return owner.eNotificationRequired();
222   }
223
224   public NotificationChain inverseAdd(Object JavaDoc object, NotificationChain notifications)
225   {
226     InternalEObject internalEObject = (InternalEObject) object;
227     if (hasNavigableInverse())
228     {
229       if (!hasInstanceClass())
230       {
231         return
232           internalEObject.eInverseAdd
233             (owner,
234              internalEObject.eClass().getFeatureID(getInverseEReference()),
235              null,
236              notifications);
237       }
238       else
239       {
240         return
241           internalEObject.eInverseAdd
242             (owner,
243              getInverseFeatureID(),
244              getInverseFeatureClass(),
245              notifications);
246       }
247     }
248     else
249     {
250       return
251         internalEObject.eInverseAdd
252           (owner,
253            InternalEObject.EOPPOSITE_FEATURE_BASE - getFeatureID(),
254            null,
255            notifications);
256     }
257   }
258
259   public NotificationChain inverseRemove(Object JavaDoc object, NotificationChain notifications)
260   {
261     InternalEObject internalEObject = (InternalEObject) object;
262     if (hasNavigableInverse())
263     {
264       if (!hasInstanceClass())
265       {
266         return
267           internalEObject.eInverseRemove
268             (owner,
269              internalEObject.eClass().getFeatureID(getInverseEReference()),
270              null,
271              notifications);
272       }
273       else
274       {
275         return
276           internalEObject.eInverseRemove
277             (owner,
278              getInverseFeatureID(),
279              getInverseFeatureClass(),
280              notifications);
281       }
282     }
283     else
284     {
285       return
286         internalEObject.eInverseRemove
287           (owner,
288            InternalEObject.EOPPOSITE_FEATURE_BASE - getFeatureID(),
289            null,
290            notifications);
291     }
292   }
293
294   /**
295    * Resolve to compare objects but do not modify list
296    */

297   public boolean contains(Object JavaDoc object)
298   {
299     if (isEObject())
300     {
301       if (size > 4)
302       {
303         if (isContainment())
304         {
305           if (!(object instanceof EObject)) return false;
306           InternalEObject eObject = (InternalEObject)object;
307           return
308             eObject.eContainer() == owner &&
309               (hasNavigableInverse() ?
310                  eObject.eBaseStructuralFeatureID(eObject.eContainerFeatureID(), dataClass) == getInverseFeatureID() :
311                  InternalEObject.EOPPOSITE_FEATURE_BASE - eObject.eContainerFeatureID() == getFeatureID());
312         }
313         // We can also optimize single valued reverse.
314
//
315
else if (hasNavigableInverse() && !hasManyInverse())
316         {
317           return object instanceof EObject && ((EObject)object).eGet(getInverseEReference()) == owner;
318         }
319       }
320
321       boolean result = super.contains(object);
322       if (hasProxies() && !result)
323       {
324         for (int i = 0; i < size; ++i)
325         {
326           EObject eObject = resolveProxy((EObject)data[i]);
327           if (eObject == object)
328           {
329             return true;
330           }
331         }
332       }
333       return result;
334     }
335     else
336     {
337       return super.contains(object);
338     }
339   }
340
341   public int indexOf(Object JavaDoc object)
342   {
343     int index = super.indexOf(object);
344     if (index >= 0)
345       return index;
346
347     // EATM This might be better written as a single loop for the EObject case?
348
//
349
if (isEObject())
350     {
351       for (int i = 0; i < size; ++i)
352       {
353         EObject eObject = resolveProxy((EObject)data[i]);
354         if (eObject == object)
355         {
356           return i;
357         }
358       }
359     }
360
361     return -1;
362   }
363
364   public int lastIndexOf(Object JavaDoc object)
365   {
366     int result = super.lastIndexOf(object);
367     if (isEObject () && result == -1)
368     {
369       for (int i = size - 1; i >= 0; --i)
370       {
371         EObject eObject = resolveProxy((EObject)data[i]);
372         if (eObject == object)
373         {
374           return i;
375         }
376       }
377     }
378
379     return result;
380   }
381
382   public Iterator JavaDoc basicIterator()
383   {
384     return super.basicIterator();
385   }
386
387   public ListIterator JavaDoc basicListIterator()
388   {
389     return super.basicListIterator();
390   }
391
392   public ListIterator JavaDoc basicListIterator(int index)
393   {
394     return super.basicListIterator(index);
395   }
396
397   public EObject getEObject()
398   {
399     return owner;
400   }
401
402   public Object JavaDoc get(boolean resolve)
403   {
404     return this;
405   }
406
407   public void set(Object JavaDoc newValue)
408   {
409     clear();
410     addAll((List JavaDoc)newValue);
411   }
412
413   public boolean isSet()
414   {
415     return !isEmpty();
416   }
417
418   public void unset()
419   {
420     clear();
421   }
422
423   public static class UnmodifiableEList
424     extends BasicEList.UnmodifiableEList
425     implements InternalEList.Unsettable, EStructuralFeature.Setting
426   {
427     public static class FastCompare extends EcoreEList.UnmodifiableEList
428     {
429       public FastCompare(InternalEObject owner, EStructuralFeature eStructuralFeature, int size, Object JavaDoc [] data)
430       {
431         super(owner, eStructuralFeature, size, data);
432       }
433       
434       protected boolean useEquals()
435       {
436         return false;
437       }
438     }
439     
440     protected final InternalEObject owner;
441     protected final EStructuralFeature eStructuralFeature;
442
443     public UnmodifiableEList(InternalEObject owner, EStructuralFeature eStructuralFeature, int size, Object JavaDoc [] data)
444     {
445       super(size, data);
446       this.owner = owner;
447       this.eStructuralFeature = eStructuralFeature;
448     }
449
450     public List JavaDoc basicList()
451     {
452       return super.basicList();
453     }
454
455     public Iterator JavaDoc basicIterator()
456     {
457       return super.basicIterator();
458     }
459
460     public ListIterator JavaDoc basicListIterator()
461     {
462       return super.basicListIterator();
463     }
464
465     public ListIterator JavaDoc basicListIterator(int index)
466     {
467       return super.basicListIterator(index);
468     }
469
470     public EObject getEObject()
471     {
472       return owner;
473     }
474
475     public EStructuralFeature getEStructuralFeature()
476     {
477       return eStructuralFeature;
478     }
479
480     public Object JavaDoc get(boolean resolve)
481     {
482       return this;
483     }
484
485     public void set(Object JavaDoc newValue)
486     {
487       throw new UnsupportedOperationException JavaDoc();
488     }
489
490     public boolean isSet()
491     {
492       return !isEmpty();
493     }
494
495     public void unset()
496     {
497       throw new UnsupportedOperationException JavaDoc();
498     }
499
500     public NotificationChain basicRemove(Object JavaDoc object, NotificationChain notifications)
501     {
502       throw new UnsupportedOperationException JavaDoc();
503     }
504
505     public NotificationChain basicAdd(Object JavaDoc object, NotificationChain notifications)
506     {
507       throw new UnsupportedOperationException JavaDoc();
508     }
509   }
510
511   public static class Generic extends EcoreEList
512   {
513     public static final int IS_SET = 0x0001;
514     public static final int IS_UNSETTABLE = 0x0002;
515     public static final int HAS_INSTANCE_CLASS = 0x0004;
516     public static final int HAS_NAVIGABLE_INVERSE = 0x0008;
517     public static final int HAS_MANY_INVERSE = 0x0010;
518     public static final int IS_CONTAINMENT = 0x0020;
519     public static final int IS_CONTAINER = 0x0040;
520     public static final int IS_UNIQUE = 0x0080;
521     public static final int IS_PRIMITIVE = 0x0100;
522     public static final int IS_ENUM = 0x0200;
523     public static final int IS_EOBJECT = 0x0400;
524     public static final int HAS_PROXIES = 0x0800;
525
526     public static Class JavaDoc wrapperClassFor(Class JavaDoc javaClass)
527     {
528       if (javaClass == null)
529       {
530         return Object JavaDoc.class;
531       }
532       else
533       {
534         return EcoreUtil.wrapperClassFor(javaClass);
535       }
536     }
537
538     public static int kind(EStructuralFeature eStructuralFeature)
539     {
540       int result = 0;
541
542       EClassifier eClassifier = eStructuralFeature.getEType();
543
544       if (eClassifier.getInstanceClass() != null)
545       {
546         result |= HAS_INSTANCE_CLASS;
547       }
548
549       if (eStructuralFeature.isUnsettable())
550       {
551         result |= IS_UNSETTABLE;
552       }
553
554       if (eStructuralFeature instanceof EReference)
555       {
556         EReference eReference = (EReference)eStructuralFeature;
557         EReference inverseEReference = eReference.getEOpposite();
558         if (eReference.isContainment())
559         {
560           result |= IS_CONTAINMENT;
561         }
562
563         if (inverseEReference != null)
564         {
565           // This forces the feature ids to be assigned.
566
//
567
inverseEReference.getEContainingClass().getFeatureCount();
568           result |= HAS_NAVIGABLE_INVERSE;
569           if (inverseEReference.isMany())
570           {
571             result |= HAS_MANY_INVERSE;
572           }
573           if (inverseEReference.isContainment())
574           {
575             result |= IS_CONTAINER;
576           }
577         }
578
579         if (eReference.isResolveProxies())
580         {
581           result |= HAS_PROXIES;
582         }
583
584         result |= IS_EOBJECT;
585       }
586       else // if (eStructuralFeature instanceof EAttribute
587
{
588         if (eClassifier instanceof EEnum)
589         {
590           result |= IS_ENUM;
591         }
592         else
593         {
594           Class JavaDoc instanceClass = eClassifier.getInstanceClass();
595           if (instanceClass != null && instanceClass.isPrimitive())
596           {
597             result |= IS_PRIMITIVE;
598           }
599         }
600       }
601
602       if (eStructuralFeature.isUnique())
603       {
604         result |= IS_UNIQUE;
605       }
606
607       return result;
608     }
609
610     protected int kind;
611
612     public Generic(int kind, Class JavaDoc dataClass, InternalEObject owner)
613     {
614       super(dataClass, owner);
615       this.kind = kind;
616     }
617
618     protected boolean useEquals()
619     {
620       // We can use == for EObjects and EnumLiterals.
621
//
622
return (kind & (IS_EOBJECT | IS_ENUM)) == 0;
623     }
624
625     protected boolean canContainNull()
626     {
627       return (kind & (IS_EOBJECT | IS_PRIMITIVE | IS_ENUM)) == 0;
628     }
629
630     protected boolean isUnique()
631     {
632       return (kind & IS_UNIQUE) != 0;
633     }
634
635     protected boolean hasInverse()
636     {
637       return (kind & (HAS_NAVIGABLE_INVERSE | IS_CONTAINMENT)) != 0;
638     }
639
640     protected boolean hasManyInverse()
641     {
642       return (kind & HAS_MANY_INVERSE) != 0;
643     }
644
645     protected boolean hasNavigableInverse()
646     {
647       return (kind & HAS_NAVIGABLE_INVERSE) != 0;
648     }
649
650     protected boolean isEObject()
651     {
652       return (kind & IS_EOBJECT) != 0;
653     }
654
655     protected boolean isContainment()
656     {
657       return (kind & IS_CONTAINMENT) != 0;
658     }
659
660     protected boolean hasProxies()
661     {
662       return (kind & HAS_PROXIES) != 0;
663     }
664
665     protected boolean hasInstanceClass()
666     {
667       return (kind & HAS_INSTANCE_CLASS) != 0;
668     }
669
670     protected boolean isContainer()
671     {
672       return (kind & IS_CONTAINER) != 0;
673     }
674
675     protected boolean isUnsettable()
676     {
677       return (kind & IS_UNSETTABLE) != 0;
678     }
679
680     public boolean isSet()
681     {
682       return isUnsettable() ? (kind & IS_SET) != 0 : !isEmpty();
683     }
684
685     public void unset()
686     {
687       super.unset();
688       if (isUnsettable())
689       {
690         if (isNotificationRequired())
691         {
692           boolean oldIsSet = (kind & IS_SET) != 0;
693           kind &= ~IS_SET;
694           owner.eNotify(createNotification(Notification.UNSET, oldIsSet, false));
695         }
696         else
697         {
698           kind &= ~IS_SET;
699         }
700       }
701     }
702
703     protected void didChange()
704     {
705       kind |= IS_SET;
706     }
707   }
708
709   public static class Dynamic extends Generic
710   {
711     protected EStructuralFeature eStructuralFeature;
712
713     public Dynamic(InternalEObject owner, EStructuralFeature eStructuralFeature)
714     {
715       super(kind(eStructuralFeature), wrapperClassFor(eStructuralFeature.getEType().getInstanceClass()), owner);
716       this.eStructuralFeature = eStructuralFeature;
717     }
718
719     public Dynamic(int kind, InternalEObject owner, EStructuralFeature eStructuralFeature)
720     {
721       super(kind, wrapperClassFor(eStructuralFeature.getEType().getInstanceClass()), owner);
722       this.eStructuralFeature = eStructuralFeature;
723     }
724
725     public Dynamic(int kind, Class JavaDoc dataClass, InternalEObject owner, EStructuralFeature eStructuralFeature)
726     {
727       super(kind, dataClass, owner);
728       this.eStructuralFeature = eStructuralFeature;
729     }
730
731     public EStructuralFeature getEStructuralFeature()
732     {
733       return eStructuralFeature;
734     }
735   }
736 }
737
Popular Tags