1 19 package org.netbeans.modules.javacore.jmiimpl.javamodel; 20 21 import java.lang.reflect.Array ; 22 import java.util.Collection ; 23 import java.util.ConcurrentModificationException ; 24 import java.util.Iterator ; 25 26 import javax.jmi.reflect.RefObject; 27 28 import org.netbeans.api.mdr.events.AssociationEvent; 29 import org.netbeans.mdr.handlers.AssociationHandler; 30 import org.netbeans.mdr.storagemodel.MdrStorage; 31 import org.netbeans.mdr.util.EventNotifier; 32 33 40 public class ReferenceColWrapper implements Collection { 41 protected final MdrStorage storage; 42 protected final AssociationHandler source; 43 protected final EventNotifier.Association notifier; 44 protected final RefObject fixed; 45 protected final String endName; 46 47 private Collection inner; 48 private int modCount = 0; 49 50 protected final MetadataElement parent; 51 protected final int changeMask; 52 53 private TypeVerifier typeVerifier; 54 55 56 57 58 59 public ReferenceColWrapper(MdrStorage storage, AssociationHandler source, RefObject fixed, String endName, MetadataElement parent, int changeMask, Collection inner) { 60 this(storage, source, fixed, endName, parent, changeMask); 61 setInnerList(inner); 62 } 63 64 protected ReferenceColWrapper(MdrStorage storage, AssociationHandler source, RefObject fixed, String endName, MetadataElement parent, int changeMask) { 65 this.storage = storage; 66 this.source = source; 67 this.notifier = storage == null ? null : storage.getEventNotifier().ASSOCIATION; 68 this.fixed = fixed; 69 this.endName = endName; 70 this.parent = parent; 71 this.changeMask = changeMask; 72 } 73 74 public void setInnerList(Collection inner) { 75 modCount++; 76 this.inner = inner; 77 if (inner instanceof TypeVerifier) { 78 typeVerifier = (TypeVerifier) inner; 79 } 80 } 81 82 public Collection getInnerCollection() { 83 return inner; 84 } 85 86 protected int getModCount() { 87 return modCount; 88 } 89 90 protected void objectChanged(Object obj) { 91 if (parent == null) { 92 if (obj instanceof MetadataElement) { 93 ((MetadataElement) obj).objectChanged(changeMask); 94 } 95 } else { 96 parent.objectChanged(changeMask); 97 } 98 } 99 100 public void setTypeVerifier(TypeVerifier newTypeVerifier) { 101 this.typeVerifier = newTypeVerifier; 102 } 103 104 105 protected void lock(boolean writeAccess) { 106 storage.getRepository().beginTrans(writeAccess); 107 } 108 109 protected void unlock() { 110 storage.getRepository().endTrans(); 111 } 112 113 protected void unlock(boolean fail) { 114 storage.getRepository().endTrans(fail); 115 } 116 117 protected void checkType(Object obj) throws javax.jmi.reflect.TypeMismatchException { 118 if (typeVerifier != null) 119 typeVerifier.checkType(obj); 120 } 121 122 protected void checkWrite() { 123 if (source == null) { 124 throw new UnsupportedOperationException (); 125 } 126 } 127 128 129 130 public boolean contains(Object obj) { 131 lock(false); 132 try { 133 return inner.contains(obj); 134 } finally { 135 unlock(); 136 } 137 } 138 139 public Iterator iterator() { 140 lock(false); 141 try { 142 return new ReferenceIteratorWrapper(inner.iterator()); 143 } finally { 144 unlock(); 145 } 146 } 147 148 public int size() { 149 lock(false); 150 try { 151 return inner.size(); 152 } finally { 153 unlock(); 154 } 155 } 156 157 public boolean isEmpty() { 158 lock(false); 159 try { 160 return inner.isEmpty(); 161 } finally { 162 unlock(); 163 } 164 } 165 166 public boolean containsAll(Collection collection) { 167 lock(false); 168 try { 169 return inner.containsAll(collection); 170 } finally { 171 unlock(); 172 } 173 } 174 175 public Object [] toArray(Object [] obj) { 176 lock(false); 177 try { 178 Object [] value = inner.toArray(); 182 Object [] result = obj; 185 if (value.length > result.length) { 186 result = (Object []) Array.newInstance(obj.getClass().getComponentType(), value.length); 187 } else if (value.length < result.length) { 188 result[value.length] = null; 189 } 190 System.arraycopy(value, 0, result, 0, value.length); 191 return result; 192 } finally { 193 unlock(); 194 } 195 } 196 197 public Object [] toArray() { 198 return toArray(new Object [size()]); 199 } 200 201 public boolean equals(Object object) { 202 if (object == this) return true; 203 if (!(object instanceof Collection )) return false; 204 lock(false); 205 try { 206 Iterator it1 = iterator(); 207 Iterator it2 = ((Collection ) object).iterator(); 208 while(it1.hasNext() && it2.hasNext()) { 209 Object o1 = it1.next(); 210 Object o2 = it2.next(); 211 if (!(o1==null ? o2==null : o1.equals(o2))) 212 return false; 213 } 214 return !(it1.hasNext() || it2.hasNext()); 215 } finally { 216 unlock(); 217 } 218 } 219 220 public int hashCode() { 221 lock(false); 222 try { 223 int hashCode = 1; 224 for (Iterator it = iterator(); it.hasNext();) { 225 Object obj = it.next(); 226 hashCode = 31*hashCode + (obj==null ? 0 : obj.hashCode()); 227 } 228 return hashCode; 229 } finally { 230 unlock(); 231 } 232 } 233 234 235 236 public void clear() { 237 checkWrite(); 238 boolean fail = true; 239 lock(true); 240 try { 241 Object elements[] = inner.toArray(); 242 for (int i = 0; i < elements.length; i++) { 243 remove(elements[i]); 244 } 245 fail = false; 246 } finally { 247 unlock(fail); 248 } 249 } 250 251 public boolean addAll(Collection collection) { 252 checkWrite(); 253 boolean fail = true; 254 lock(true); 255 try { 256 boolean result = false; 257 for (Iterator it = collection.iterator(); it.hasNext();) { 258 result |= add(it.next()); 259 } 260 fail = false; 261 return result; 262 } finally { 263 unlock(fail); 264 } 265 } 266 267 public boolean retainAll(Collection collection) { 268 checkWrite(); 269 boolean fail = true; 270 lock(true); 271 try { 272 boolean result = false; 273 Object elements[] = inner.toArray(); 274 for (int i = 0; i < elements.length; i++) { 275 Object o = elements[i]; 276 if (!collection.contains(o)) { 277 remove(o); 278 result = true; 279 } 280 } 281 fail = false; 282 return result; 283 } finally { 284 unlock(fail); 285 } 286 } 287 288 public boolean removeAll(Collection collection) { 289 checkWrite(); 290 boolean fail = true; 291 lock(true); 292 try { 293 boolean result = false; 294 for (Iterator it = collection.iterator(); it.hasNext();) { 295 result |= remove(it.next()); 296 } 297 fail = false; 298 return result; 299 } finally { 300 unlock(fail); 301 } 302 } 303 304 public boolean remove(Object obj) { 305 checkWrite(); 306 checkType(obj); 307 boolean fail = true; 308 lock(true); 309 try { 310 if (storage.eventsEnabled()) { 311 AssociationEvent event = new AssociationEvent( 312 source, 313 AssociationEvent.EVENT_ASSOCIATION_REMOVE, 314 fixed, 315 endName, 316 (RefObject) obj, 317 null, 318 AssociationEvent.POSITION_NONE); 319 notifier.firePlannedChange(source, event); 320 } 321 boolean result = inner.remove(obj); 322 objectChanged(obj); 323 fail = false; 324 return result; 325 } finally { 326 unlock(fail); 327 } 328 } 329 330 public boolean add(Object obj) { 331 checkWrite(); 332 checkType(obj); 333 boolean fail = true; 334 lock(true); 335 try { 336 if (storage.eventsEnabled()) { 337 AssociationEvent event = new AssociationEvent( 338 source, 339 AssociationEvent.EVENT_ASSOCIATION_ADD, 340 fixed, 341 endName, 342 null, 343 (RefObject) obj, 344 AssociationEvent.POSITION_NONE); 345 notifier.firePlannedChange(source, event); 346 } 347 boolean result = inner.add(obj); 348 objectChanged(obj); 349 fail = false; 350 return result; 351 } finally { 352 unlock(fail); 353 } 354 } 355 356 357 358 protected class ReferenceIteratorWrapper implements Iterator { 359 protected Iterator innerIterator; 360 protected Object lastRead = null; 361 protected final int modCount; 362 363 public ReferenceIteratorWrapper(Iterator innerIterator) { 364 this.innerIterator = innerIterator; 365 this.modCount = getParentModCount(); 366 } 367 368 protected int getParentModCount() { 369 return ReferenceColWrapper.this.getModCount(); 370 } 371 372 protected void testModCount() throws ConcurrentModificationException { 373 if (modCount != getParentModCount()) 374 throw new ConcurrentModificationException (); 375 } 376 377 public boolean hasNext() { 378 testModCount(); 379 lock(false); 380 try { 381 return innerIterator.hasNext(); 382 } finally { 383 unlock(); 384 } 385 } 386 387 public Object next() { 388 testModCount(); 389 lock(false); 390 try { 391 return (lastRead = innerIterator.next()); 392 } finally { 393 unlock(); 394 } 395 } 396 397 public void remove() { 398 checkWrite(); 399 testModCount(); 400 boolean fail = true; 402 lock(true); 403 try { 404 if (storage.eventsEnabled()) { 405 AssociationEvent event = new AssociationEvent( 406 source, 407 AssociationEvent.EVENT_ASSOCIATION_REMOVE, 408 fixed, 409 endName, 410 (RefObject) lastRead, 411 null, 412 AssociationEvent.POSITION_NONE); 413 notifier.firePlannedChange(source, event); 414 } 415 innerIterator.remove(); 416 objectChanged(lastRead); 417 fail = false; 418 } finally { 419 unlock(fail); 420 } 421 } 422 } 423 } 424 | Popular Tags |