1 19 package org.netbeans.modules.javacore.jmiimpl.javamodel; 20 21 import java.util.*; 22 import org.netbeans.modules.javacore.JMManager; 23 import org.netbeans.modules.javacore.internalapi.JavaMetamodel; 24 import org.openide.ErrorManager; 25 26 import org.openide.util.WeakSet; 27 28 public class LightAttrList implements List { 29 private List innerList; 30 private int modCount = 0; 31 32 private final MetadataElement parent; 33 private final int changeMask; 34 private List hardReferences; 35 36 private final WeakSet iterators = new WeakSet(); 39 private RuntimeException exception = null; 40 41 42 private void lock(boolean writeLock) { 43 JavaMetamodel.getDefaultRepository().beginTrans(writeLock); 44 } 45 46 private void unlock() { 47 unlock(false); 48 } 49 50 private void unlock(boolean rollback) { 51 JavaMetamodel.getDefaultRepository().endTrans(rollback); 52 } 53 54 public LightAttrList(List innerList, MetadataElement parent, int changeMask) { 55 this(innerList, parent, changeMask, false); 56 } 57 58 public LightAttrList(List innerList, MetadataElement parent, int changeMask, boolean hardReference) { 59 this.parent = parent; 60 this.changeMask = changeMask; 61 setInnerList(innerList); 62 if (hardReference) { 63 updateHardReferences(true); 64 } 65 } 66 67 private void updateHardReferences(boolean parentChanged) { 68 Object [] elements=innerList.toArray(); 69 hardReferences = new ArrayList(elements.length); 70 for (int i=0;i<elements.length;i++) { 71 Object obj = elements[i]; 72 if (parentChanged) parentChanged(obj); 73 hardReferences.add(obj); 74 } 75 } 76 77 public void setInnerList(List innerList) { 78 setInnerList(innerList, true); 79 } 80 81 public void setInnerList(List innerList, boolean parentChanged) { 82 lock(false); 83 try { 84 modCount++; 85 this.innerList = innerList; 86 if (hardReferences != null) { 87 updateHardReferences(parentChanged); 88 } 89 90 if (iterators != null) { 92 Object [] iters = iterators.toArray(); 93 for (int i = 0; i < iters.length; i++) { 94 if (((LightAttrListIterator) iters[i]).modCount >= 0) { 95 exception = new RuntimeException (); 96 break; 97 } 98 } 99 } 100 } finally { 102 unlock(); 103 } 104 } 105 106 public List getInnerList() { 107 lock(false); 108 try { 109 return innerList; 110 } finally { 111 unlock(); 112 } 113 } 114 115 protected void objectChanged() { 116 if (parent != null) 117 parent.objectChanged(changeMask); 118 } 119 120 protected void parentChanged(Object obj) { 121 if (obj instanceof MetadataElement) { 122 ((MetadataElement) obj).parentChanged(); 123 } 124 } 125 126 128 public boolean remove(Object obj) { 129 boolean fail = true; 130 lock(true); 131 try { 132 objectChanged(); 133 boolean result = innerList.remove(obj); 134 if (hardReferences != null && result) hardReferences.remove(obj); 135 fail = false; 136 return result; 137 } finally { 138 unlock(fail); 139 } 140 } 141 142 public Object set(int param, Object obj) { 143 boolean fail = true; 144 lock(true); 145 try { 146 objectChanged(); 147 Object result = innerList.set(param, obj); 148 if (hardReferences != null) hardReferences.set(param, obj); 149 parentChanged(obj); 150 fail = false; 151 return result; 152 } finally { 153 unlock(fail); 154 } 155 } 156 157 public Object remove(int param) { 158 boolean fail = true; 159 lock(true); 160 try { 161 objectChanged(); 162 Object result = innerList.remove(param); 163 if (hardReferences != null) hardReferences.remove(param); 164 fail = false; 165 return result; 166 } finally { 167 unlock(fail); 168 } 169 } 170 171 public void add(int param, Object obj) { 172 boolean fail = true; 173 lock(true); 174 try { 175 objectChanged(); 176 innerList.add(param, obj); 177 if (hardReferences != null) hardReferences.add(param, obj); 178 parentChanged(obj); 179 fail = false; 180 } finally { 181 unlock(fail); 182 } 183 } 184 185 public boolean add(Object obj) { 186 boolean fail = true; 187 lock(true); 188 try { 189 objectChanged(); 190 boolean result = innerList.add(obj); 191 if (hardReferences != null && result) hardReferences.add(obj); 192 if (result) { 193 parentChanged(obj); 194 } 195 fail = false; 196 return result; 197 } finally { 198 unlock(fail); 199 } 200 } 201 202 public ListIterator listIterator(int param) { 203 lock(false); 204 try { 205 ListIterator result = new LightAttrListIterator(param); 206 207 if (iterators != null) iterators.add(result); 211 return result; 212 } finally { 213 unlock(); 214 } 215 } 216 217 public Iterator iterator() { 218 return listIterator(); 219 } 220 221 public ListIterator listIterator() { 222 return listIterator(0); 223 } 224 225 public List subList(int param, int param1) { 226 lock(false); 227 try { 228 return new LightAttrList(innerList.subList(param, param1), parent, changeMask); 229 } finally { 230 unlock(); 231 } 232 } 233 234 public boolean contains(Object obj) { 235 return innerList.contains(obj); 236 } 237 238 public boolean containsAll(Collection collection) { 239 return innerList.containsAll(collection); 240 } 241 242 public boolean addAll(Collection c) { 243 boolean fail = true; 244 lock(true); 245 try { 246 objectChanged(); 247 boolean result = innerList.addAll(c); 248 if (hardReferences != null) hardReferences.addAll(c); 249 if (result) { 250 for (Iterator it = c.iterator(); it.hasNext();) { 251 parentChanged(it.next()); 252 } 253 } 254 fail = false; 255 return result; 256 } finally { 257 unlock(fail); 258 } 259 } 260 261 public void clear() { 262 boolean fail = true; 263 lock(true); 264 try { 265 objectChanged(); 266 innerList.clear(); 267 if (hardReferences != null) hardReferences.clear(); 268 fail = false; 269 } finally { 270 unlock(fail); 271 } 272 } 273 274 public boolean isEmpty() { 275 return innerList.isEmpty(); 276 } 277 278 public boolean removeAll(Collection c) { 279 boolean fail = true; 280 lock(true); 281 try { 282 objectChanged(); 283 boolean result = innerList.removeAll(c); 284 if (hardReferences != null) hardReferences.removeAll(c); 285 fail = false; 286 return result; 287 } finally { 288 unlock(fail); 289 } 290 } 291 292 public boolean retainAll(Collection c) { 293 boolean fail = true; 294 lock(true); 295 try { 296 objectChanged(); 297 boolean result = innerList.retainAll(c); 298 if (hardReferences != null) hardReferences.retainAll(c); 299 fail = false; 300 return result; 301 } finally { 302 unlock(fail); 303 } 304 } 305 306 public int size() { 307 return innerList.size(); 308 } 309 310 public Object [] toArray() { 311 return innerList.toArray(); 312 } 313 314 public Object [] toArray(Object [] a) { 315 return innerList.toArray(a); 316 } 317 318 public boolean addAll(int index, Collection c) { 319 boolean fail = true; 320 lock(true); 321 try { 322 objectChanged(); 323 boolean result = innerList.addAll(index, c); 324 if (hardReferences != null) hardReferences.addAll(index, c); 325 if (result) { 326 for (Iterator it = c.iterator(); it.hasNext();) { 327 parentChanged(it.next()); 328 } 329 } 330 fail = false; 331 return result; 332 } finally { 333 unlock(fail); 334 } 335 } 336 337 public Object get(int index) { 338 return innerList.get(index); 339 } 340 341 public int indexOf(Object o) { 342 return innerList.indexOf(o); 343 } 344 345 public int lastIndexOf(Object o) { 346 return innerList.lastIndexOf(o); 347 } 348 349 class LightAttrListIterator implements ListIterator { 351 private ListIterator innerIterator; 352 private ListIterator hrIterator; 353 private int modCount = -1; 354 private final int index; 355 356 LightAttrListIterator(int param) { 357 index = param; 358 } 359 360 private int getParentModCount() { 361 return LightAttrList.this.modCount; 362 } 363 364 private void testModCount() throws ConcurrentModificationException { 365 if (this.modCount == -1) { 366 if (hardReferences != null) { 367 if (hardReferences.size() != innerList.size()) { 368 JMManager.getLog().notify(ErrorManager.INFORMATIONAL, new Exception ("Inconsistency in LightAttrList: innerList.size() == " + innerList.size() + " while hardReferences.size() == " + hardReferences.size() + ". Fixing...")); updateHardReferences(true); 370 } 371 hrIterator = hardReferences.listIterator(index); 372 } 373 innerIterator = innerList.listIterator(index); 374 this.modCount = getParentModCount(); 375 } else 376 if (getParentModCount() != modCount) { 377 JMManager.getLog().notify(ErrorManager.INFORMATIONAL, exception); 378 throw new ConcurrentModificationException(); 379 } 380 } 381 382 public void remove() { 383 boolean fail = true; 384 lock(true); 385 try { 386 testModCount(); 387 objectChanged(); 388 innerIterator.remove(); 389 if (hrIterator != null) hrIterator.remove(); 390 fail = false; 391 } finally { 392 unlock(fail); 393 } 394 } 395 396 public void add(Object obj) { 397 boolean fail = true; 398 lock(true); 399 try { 400 testModCount(); 401 objectChanged(); 402 innerIterator.add(obj); 403 if (hrIterator != null) hrIterator.add(obj); 404 parentChanged(obj); 405 fail = false; 406 } finally { 407 unlock(fail); 408 } 409 } 410 411 public void set(Object obj) { 412 boolean fail = true; 413 lock(true); 414 try { 415 testModCount(); 416 objectChanged(); 417 innerIterator.set(obj); 418 if (hrIterator != null) hrIterator.set(obj); 419 parentChanged(obj); 420 fail = false; 421 } finally { 422 unlock(fail); 423 } 424 } 425 426 public boolean hasNext() { 427 lock(false); 428 try { 429 testModCount(); 430 return innerIterator.hasNext(); 431 } finally { 432 unlock(); 433 } 434 } 435 436 public boolean hasPrevious() { 437 lock(false); 438 try { 439 testModCount(); 440 return innerIterator.hasPrevious(); 441 } finally { 442 unlock(); 443 } 444 } 445 446 public Object next() { 447 lock(false); 448 try { 449 testModCount(); 450 if (hrIterator != null) hrIterator.next(); 451 return innerIterator.next(); 452 } finally { 453 unlock(); 454 } 455 } 456 457 public int nextIndex() { 458 lock(false); 459 try { 460 testModCount(); 461 return innerIterator.nextIndex(); 462 } finally { 463 unlock(); 464 } 465 } 466 467 public Object previous() { 468 lock(false); 469 try { 470 testModCount(); 471 if (hrIterator != null) hrIterator.previous(); 472 return innerIterator.previous(); 473 } finally { 474 unlock(); 475 } 476 } 477 478 public int previousIndex() { 479 lock(false); 480 try { 481 testModCount(); 482 return innerIterator.previousIndex(); 483 } finally { 484 unlock(); 485 } 486 } 487 } 488 } 489 | Popular Tags |