1 17 package org.eclipse.emf.ecore.util; 18 19 20 import java.util.AbstractSequentialList ; 21 import java.util.Collection ; 22 import java.util.Iterator ; 23 import java.util.List ; 24 import java.util.ListIterator ; 25 import java.util.NoSuchElementException ; 26 27 import org.eclipse.emf.common.notify.NotificationChain; 28 import org.eclipse.emf.common.util.EList; 29 import org.eclipse.emf.ecore.EObject; 30 import org.eclipse.emf.ecore.EReference; 31 import org.eclipse.emf.ecore.EStructuralFeature; 32 import org.eclipse.emf.ecore.impl.EClassImpl; 33 34 35 public class EContentsEList extends AbstractSequentialList implements EList, InternalEList 36 { 37 protected final EObject eObject; 38 protected final EStructuralFeature [] eStructuralFeatures; 39 40 public EContentsEList(EObject eObject) 41 { 42 this.eObject = eObject; 43 this.eStructuralFeatures = 44 ((EClassImpl.FeatureSubsetSupplier)eObject.eClass().getEAllStructuralFeatures()).containments(); 45 } 46 47 public EContentsEList(EObject eObject, List eStructuralFeatures) 48 { 49 this.eObject = eObject; 50 this.eStructuralFeatures = new EStructuralFeature [eStructuralFeatures.size()]; 51 eStructuralFeatures.toArray(this.eStructuralFeatures); 52 } 53 54 public EContentsEList(EObject eObject, EStructuralFeature [] eStructuralFeatures) 55 { 56 this.eObject = eObject; 57 this.eStructuralFeatures = eStructuralFeatures; 58 } 59 60 protected ListIterator newListIterator() 61 { 62 return 63 resolve() ? 64 new ResolvingFeatureIteratorImpl(eObject, eStructuralFeatures) : 65 new FeatureIteratorImpl(eObject, eStructuralFeatures); 66 } 67 68 protected Iterator newIterator() 69 { 70 return newListIterator(); 71 } 72 73 protected boolean useIsSet() 74 { 75 return true; 76 } 77 78 protected boolean resolve() 79 { 80 return true; 81 } 82 83 protected boolean isIncluded(EStructuralFeature eStructuralFeature) 84 { 85 return true; 86 } 87 88 protected boolean isIncludedEntry(EStructuralFeature eStructuralFeature) 89 { 90 return eStructuralFeature instanceof EReference && ((EReference)eStructuralFeature).isContainment(); 91 } 92 93 public ListIterator listIterator(int index) 94 { 95 if (eStructuralFeatures == null) 96 { 97 if (index != 0) 98 { 99 throw new IndexOutOfBoundsException ("index=" + index + ", size=0"); 100 } 101 102 return FeatureIteratorImpl.EMPTY_ITERATOR; 103 } 104 105 ListIterator result = newListIterator(); 106 for (int i = 0; i < index; ++i) 107 { 108 result.next(); 109 } 110 return result; 111 } 112 113 public Iterator iterator() 114 { 115 if (eStructuralFeatures == null) 116 { 117 return FeatureIteratorImpl.EMPTY_ITERATOR; 118 } 119 120 Iterator result = newIterator(); 121 return result; 122 } 123 124 public int size() 125 { 126 int result = 0; 127 if (eStructuralFeatures != null) 128 { 129 for (int i = 0; i < eStructuralFeatures.length; ++i) 130 { 131 EStructuralFeature feature = eStructuralFeatures[i]; 132 if (isIncluded(feature) && (!useIsSet() || eObject.eIsSet(feature))) 133 { 134 Object value = eObject.eGet(feature, false); 135 if (FeatureMapUtil.isFeatureMap(feature)) 136 { 137 FeatureMap featureMap = (FeatureMap)value; 138 for (int j = 0, size = featureMap.size(); j < size; ++j) 139 { 140 if (isIncludedEntry(featureMap.getEStructuralFeature(j)) && featureMap.getValue(j) != null) 141 { 142 ++result; 143 } 144 } 145 } 146 else if (feature.isMany()) 147 { 148 result += ((Collection )value).size(); 149 } 150 else if (value != null) 151 { 152 ++result; 153 } 154 } 155 } 156 } 157 return result; 158 } 159 160 public boolean isEmpty() 161 { 162 if (eStructuralFeatures != null) 163 { 164 for (int i = 0; i < eStructuralFeatures.length; ++i) 165 { 166 EStructuralFeature feature = eStructuralFeatures[i]; 167 if (isIncluded(feature) && (!useIsSet() || eObject.eIsSet(feature))) 168 { 169 Object value = eObject.eGet(feature, false); 170 if (FeatureMapUtil.isFeatureMap(feature)) 171 { 172 FeatureMap featureMap = (FeatureMap)value; 173 for (int j = 0, size = featureMap.size(); j < size; ++j) 174 { 175 if (isIncludedEntry(featureMap.getEStructuralFeature(j)) && featureMap.getValue(j) != null) 176 { 177 return false; 178 } 179 } 180 } 181 else if (feature.isMany()) 182 { 183 if (!((Collection )value).isEmpty()) 184 { 185 return false; 186 } 187 } 188 else if (value != null) 189 { 190 return false; 191 } 192 } 193 } 194 } 195 return true; 196 } 197 198 public void move(int newPosition, Object o) 199 { 200 throw new UnsupportedOperationException (); 201 } 202 203 public Object move(int newPosition, int oldPosition) 204 { 205 throw new UnsupportedOperationException (); 206 } 207 208 public Object basicGet(int index) 209 { 210 return basicList().get(index); 211 } 212 213 public List basicList() 214 { 215 return 216 new EContentsEList(eObject, eStructuralFeatures) 217 { 218 protected boolean resolve() 219 { 220 return false; 221 } 222 }; 223 } 224 225 public Iterator basicIterator() 226 { 227 if (eStructuralFeatures == null) 228 { 229 return FeatureIteratorImpl.EMPTY_ITERATOR; 230 } 231 232 return new FeatureIteratorImpl(eObject, eStructuralFeatures); 233 } 234 235 public ListIterator basicListIterator() 236 { 237 if (eStructuralFeatures == null) 238 { 239 return FeatureIteratorImpl.EMPTY_ITERATOR; 240 } 241 242 return new FeatureIteratorImpl(eObject, eStructuralFeatures); 243 } 244 245 public ListIterator basicListIterator(int index) 246 { 247 if (eStructuralFeatures == null) 248 { 249 if (index < 0 || index > 1) 250 { 251 throw new IndexOutOfBoundsException ("index=" + index + ", size=0"); 252 } 253 254 return FeatureIteratorImpl.EMPTY_ITERATOR; 255 } 256 257 ListIterator result = new FeatureIteratorImpl(eObject, eStructuralFeatures); 258 for (int i = 0; i < index; ++i) 259 { 260 result.next(); 261 } 262 return result; 263 } 264 265 public NotificationChain basicRemove(Object object, NotificationChain notifications) 266 { 267 throw new UnsupportedOperationException (); 268 } 269 270 public NotificationChain basicAdd(Object object, NotificationChain notifications) 271 { 272 throw new UnsupportedOperationException (); 273 } 274 275 public void addUnique(Object object) 276 { 277 throw new UnsupportedOperationException (); 278 } 279 280 public void addUnique(int index, Object object) 281 { 282 throw new UnsupportedOperationException (); 283 } 284 285 public Object setUnique(int index, Object object) 286 { 287 throw new UnsupportedOperationException (); 288 } 289 290 public interface FeatureIterator extends Iterator 291 { 292 EStructuralFeature feature(); 293 } 294 295 public interface FeatureListIterator extends FeatureIterator, ListIterator 296 { 297 } 298 299 public static class FeatureIteratorImpl implements FeatureListIterator 300 { 301 protected final EObject eObject; 302 protected final EStructuralFeature [] eStructuralFeatures; 303 protected int featureCursor; 304 protected int cursor; 305 protected int prepared; 306 protected Object preparedResult; 307 protected EStructuralFeature preparedFeature; 308 protected EStructuralFeature feature; 309 protected boolean isHandlingFeatureMap; 310 protected ListIterator values; 311 312 public FeatureIteratorImpl(EObject eObject, List eStructuralFeatures) 313 { 314 this.eObject = eObject; 315 this.eStructuralFeatures = new EStructuralFeature [eStructuralFeatures.size()]; 316 eStructuralFeatures.toArray(this.eStructuralFeatures); 317 } 318 319 public FeatureIteratorImpl(EObject eObject, EStructuralFeature [] eStructuralFeatures) 320 { 321 this.eObject = eObject; 322 this.eStructuralFeatures = eStructuralFeatures; 323 } 324 325 protected boolean resolve() 326 { 327 return false; 328 } 329 330 protected boolean useIsSet() 331 { 332 return true; 333 } 334 335 protected boolean isIncluded(EStructuralFeature eStructuralFeature) 336 { 337 return true; 338 } 339 340 protected boolean isIncludedEntry(EStructuralFeature eStructuralFeature) 341 { 342 return eStructuralFeature instanceof EReference && ((EReference)eStructuralFeature).isContainment(); 343 } 344 345 public EStructuralFeature feature() 346 { 347 return feature; 348 } 349 350 public boolean hasNext() 351 { 352 switch (prepared) 353 { 354 case 3: 355 case 2: 356 { 357 return true; 358 } 359 case 1: 360 { 361 return false; 362 } 363 case -3: 364 { 365 values.next(); 367 } 368 default: 369 { 370 if (values == null || !scanNext(values)) 371 { 372 while (featureCursor < eStructuralFeatures.length) 373 { 374 EStructuralFeature feature = eStructuralFeatures[featureCursor++]; 375 if (isIncluded(feature) && (!useIsSet() || eObject.eIsSet(feature))) 376 { 377 Object value = eObject.eGet(feature, resolve()); 378 isHandlingFeatureMap = FeatureMapUtil.isFeatureMap(feature); 379 if (isHandlingFeatureMap || feature.isMany()) 380 { 381 values = resolve() ? ((List )value).listIterator() : ((InternalEList)value).basicListIterator(); 382 if (scanNext(values)) 383 { 384 preparedResult = values.next(); 385 if (isHandlingFeatureMap) 386 { 387 preparedResult = ((FeatureMap.Entry)preparedResult).getValue(); 388 } 389 preparedFeature = feature; 390 prepared = 3; 391 return true; 392 } 393 } 394 else if (value != null) 395 { 396 values = null; 397 preparedResult = value; 398 preparedFeature = feature; 399 prepared = 2; 400 return true; 401 } 402 } 403 } 404 values = null; 405 isHandlingFeatureMap = false; 406 prepared = 1; 407 return false; 408 } 409 else 410 { 411 preparedResult = values.next(); 412 if (isHandlingFeatureMap) 413 { 414 preparedResult = ((FeatureMap.Entry)preparedResult).getValue(); 415 } 416 prepared = 3; 417 return true; 418 } 419 } 420 } 421 } 422 423 protected boolean scanNext(ListIterator values) 424 { 425 if (isHandlingFeatureMap) 426 { 427 while (values.hasNext()) 428 { 429 FeatureMap.Entry entry = (FeatureMap.Entry)values.next(); 430 EStructuralFeature entryFeature = entry.getEStructuralFeature(); 431 if (isIncludedEntry(entryFeature) && entry.getValue() != null) 432 { 433 values.previous(); 434 return true; 435 } 436 } 437 return false; 438 } 439 else 440 { 441 return values.hasNext(); 442 } 443 } 444 445 public Object next() 446 { 447 if (hasNext()) 448 { 449 ++cursor; 450 prepared = 0; 451 feature = preparedFeature; 452 return preparedResult; 453 } 454 else 455 { 456 throw new NoSuchElementException (); 457 } 458 } 459 460 public int nextIndex() 461 { 462 return cursor; 463 } 464 465 public boolean hasPrevious() 466 { 467 switch (prepared) 468 { 469 case -3: 470 case -2: 471 { 472 return true; 473 } 474 case -1: 475 { 476 return false; 477 } 478 case 3: 479 { 480 values.previous(); 482 } 483 default: 484 { 485 if (values == null || !scanPrevious(values)) 486 { 487 while (featureCursor > 0) 488 { 489 EStructuralFeature feature = eStructuralFeatures[--featureCursor]; 490 if (isIncluded(feature) && (!useIsSet() || eObject.eIsSet(feature))) 491 { 492 Object value = eObject.eGet(feature, resolve()); 493 isHandlingFeatureMap = FeatureMapUtil.isFeatureMap(feature); 494 if (isHandlingFeatureMap || feature.isMany()) 495 { 496 List list = (List )value; 497 values = resolve() ? list.listIterator(list.size()) : ((InternalEList)list).basicListIterator(list.size()); 498 if (scanPrevious(values)) 499 { 500 preparedResult = values.previous(); 501 if (isHandlingFeatureMap) 502 { 503 preparedResult = ((FeatureMap.Entry)preparedResult).getValue(); 504 } 505 preparedFeature = feature; 506 prepared = -3; 507 return true; 508 } 509 } 510 else if (value != null) 511 { 512 values = null; 513 preparedResult = value; 514 preparedFeature = feature; 515 prepared = -2; 516 return true; 517 } 518 } 519 } 520 values = null; 521 prepared = -1; 522 return false; 523 } 524 else 525 { 526 preparedResult = values.previous(); 527 if (isHandlingFeatureMap) 528 { 529 preparedResult = ((FeatureMap.Entry)preparedResult).getValue(); 530 } 531 prepared = -3; 532 return true; 533 } 534 } 535 } 536 } 537 538 protected boolean scanPrevious(ListIterator values) 539 { 540 if (isHandlingFeatureMap) 541 { 542 while (values.hasPrevious()) 543 { 544 FeatureMap.Entry entry = (FeatureMap.Entry)values.previous(); 545 EStructuralFeature entryFeature = entry.getEStructuralFeature(); 546 if (isIncludedEntry(entryFeature) && entry.getValue() != null) 547 { 548 values.next(); 549 return true; 550 } 551 } 552 return false; 553 } 554 else 555 { 556 return values.hasPrevious(); 557 } 558 } 559 560 public Object previous() 561 { 562 if (hasPrevious()) 563 { 564 --cursor; 565 prepared = 0; 566 feature = preparedFeature; 567 return preparedResult; 568 } 569 else 570 { 571 throw new NoSuchElementException (); 572 } 573 } 574 575 public int previousIndex() 576 { 577 return cursor - 1; 578 } 579 580 public void add(Object o) 581 { 582 throw new UnsupportedOperationException (); 583 } 584 585 public void remove() 586 { 587 throw new UnsupportedOperationException (); 588 } 589 590 public void set(Object o) 591 { 592 throw new UnsupportedOperationException (); 593 } 594 595 public static final ListIterator EMPTY_ITERATOR = 596 new FeatureIteratorImpl(null, (EStructuralFeature [] )null) 597 { 598 public boolean hasNext() 599 { 600 return false; 601 } 602 603 public boolean hasPrevious() 604 { 605 return false; 606 } 607 }; 608 } 609 610 public static class ResolvingFeatureIteratorImpl extends FeatureIteratorImpl 611 { 612 public ResolvingFeatureIteratorImpl(EObject eObject, List eStructuralFeatures) 613 { 614 super(eObject, eStructuralFeatures); 615 } 616 617 public ResolvingFeatureIteratorImpl(EObject eObject, EStructuralFeature [] eStructuralFeatures) 618 { 619 super(eObject, eStructuralFeatures); 620 } 621 622 protected boolean resolve() 623 { 624 return true; 625 } 626 } 627 } 628 | Popular Tags |