1 22 package org.jboss.ejb.plugins.cmp.jdbc.bridge; 23 24 import java.util.Collection ; 25 import java.util.ConcurrentModificationException ; 26 import java.util.ArrayList ; 27 import java.util.Iterator ; 28 import java.util.List ; 29 import java.util.Set ; 30 import java.util.HashSet ; 31 import javax.ejb.EJBException ; 32 import javax.ejb.EJBLocalObject ; 33 import javax.ejb.NoSuchObjectLocalException ; 34 35 import org.jboss.ejb.EntityEnterpriseContext; 36 import org.jboss.ejb.LocalProxyFactory; 37 38 47 public class RelationSet implements Set 48 { 49 private JDBCCMRFieldBridge cmrField; 50 private EntityEnterpriseContext ctx; 51 private List [] setHandle; 52 private boolean readOnly; 53 private Class relatedLocalInterface; 54 55 public RelationSet( 64 JDBCCMRFieldBridge cmrField, 65 EntityEnterpriseContext ctx, 66 List [] setHandle, 67 boolean readOnly) 68 { 69 70 this.cmrField = cmrField; 71 this.ctx = ctx; 72 this.setHandle = setHandle; 73 this.readOnly = readOnly; 74 relatedLocalInterface = cmrField.getRelatedLocalInterface(); 75 } 76 77 private List getIdList() 78 { 79 if(setHandle[0] == null) 80 { 81 throw new IllegalStateException ("A CMR collection may only be used " + 82 "within the transction in which it was created"); 83 } 84 return setHandle[0]; 85 } 86 87 public int size() 88 { 89 List idList = getIdList(); 90 return idList.size(); 91 } 92 93 public boolean isEmpty() 94 { 95 List idList = getIdList(); 96 return idList.isEmpty(); 97 } 98 99 public boolean add(Object o) 100 { 101 if(o == null) 102 { 103 throw new IllegalArgumentException ("Null cannot be added to a CMR " + 104 "relationship collection"); 105 } 106 107 checkForPKChange(); 108 109 List idList = getIdList(); 110 if(readOnly) 111 { 112 throw new EJBException ("This collection is a read-only snapshot"); 113 } 114 115 if(cmrField.isReadOnly()) 116 { 117 throw new EJBException ("Field is read-only: " + 118 cmrField.getFieldName()); 119 } 120 121 if(!relatedLocalInterface.isInstance(o)) 122 { 123 String msg = "Object must be an instance of " + 124 relatedLocalInterface.getName() + ", but is an isntance of ["; 125 Class [] classes = o.getClass().getInterfaces(); 126 for(int i = 0; i < classes.length; i++) 127 { 128 if(i > 0) msg += ", "; 129 msg += classes[i].getName(); 130 } 131 msg += "]"; 132 throw new IllegalArgumentException (msg); 133 } 134 135 Object id = getPrimaryKey((EJBLocalObject ) o); 136 if(idList.contains(id)) 137 { 138 return false; 139 } 140 cmrField.createRelationLinks(ctx, id); 141 return true; 142 } 143 144 public boolean addAll(Collection c) 145 { 146 if(readOnly) 147 { 148 throw new EJBException ("This collection is a read-only snapshot"); 149 } 150 if(cmrField.isReadOnly()) 151 { 152 throw new EJBException ("Field is read-only: " + 153 cmrField.getFieldName()); 154 } 155 156 if(c == null) 157 { 158 return false; 159 } 160 161 boolean isModified = false; 162 163 Iterator iterator = (new HashSet (c)).iterator(); 164 while(iterator.hasNext()) 165 { 166 isModified = add(iterator.next()) || isModified; 167 } 168 return isModified; 169 } 170 171 public boolean remove(Object o) 172 { 173 List idList = getIdList(); 174 if(readOnly) 175 { 176 throw new EJBException ("This collection is a read-only snapshot"); 177 } 178 if(cmrField.isReadOnly()) 179 { 180 throw new EJBException ("Field is read-only: " + 181 cmrField.getFieldName()); 182 } 183 184 checkForPKChange(); 185 186 if(!relatedLocalInterface.isInstance(o)) 187 { 188 throw new IllegalArgumentException ("Object must be an instance of " + 189 relatedLocalInterface.getName()); 190 } 191 192 Object id = getPrimaryKey((EJBLocalObject ) o); 193 if(!idList.contains(id)) 194 { 195 return false; 196 } 197 cmrField.destroyRelationLinks(ctx, id); 198 return true; 199 } 200 201 public boolean removeAll(Collection c) 202 { 203 if(readOnly) 204 { 205 throw new EJBException ("This collection is a read-only snapshot"); 206 } 207 if(cmrField.isReadOnly()) 208 { 209 throw new EJBException ("Field is read-only: " + 210 cmrField.getFieldName()); 211 } 212 213 if(c == null) 214 { 215 return false; 216 } 217 218 boolean isModified = false; 219 220 Iterator iterator = (new HashSet (c)).iterator(); 221 while(iterator.hasNext()) 222 { 223 isModified = remove(iterator.next()) || isModified; 224 } 225 return isModified; 226 } 227 228 public void clear() 229 { 230 checkForPKChange(); 231 232 List idList = getIdList(); 233 if(readOnly) 234 { 235 throw new EJBException ("This collection is a read-only snapshot"); 236 } 237 if(cmrField.isReadOnly()) 238 { 239 throw new EJBException ("Field is read-only: " + 240 cmrField.getFieldName()); 241 } 242 243 Iterator iterator = (new ArrayList (idList)).iterator(); 244 while(iterator.hasNext()) 245 { 246 cmrField.destroyRelationLinks(ctx, iterator.next()); 247 } 248 } 249 250 public boolean retainAll(Collection c) 251 { 252 List idList = getIdList(); 253 if(readOnly) 254 { 255 throw new EJBException ("This collection is a read-only snapshot"); 256 } 257 if(cmrField.isReadOnly()) 258 { 259 throw new EJBException ("Field is read-only: " + 260 cmrField.getFieldName()); 261 } 262 263 checkForPKChange(); 264 265 if(c == null) 266 { 267 if(idList.size() == 0) 268 { 269 return false; 270 } 271 clear(); 272 return true; 273 } 274 275 List argIds = new ArrayList (); 277 Iterator iterator = c.iterator(); 278 while(iterator.hasNext()) 279 { 280 EJBLocalObject localObject = (EJBLocalObject ) iterator.next(); 281 Object relatedId = getPrimaryKey(localObject); 282 argIds.add(relatedId); 283 } 284 285 boolean isModified = false; 286 287 iterator = (new ArrayList (idList)).iterator(); 288 while(iterator.hasNext()) 289 { 290 Object id = iterator.next(); 291 if(!argIds.contains(id)) 292 { 293 cmrField.destroyRelationLinks(ctx, id); 294 isModified = true; 295 } 296 } 297 return isModified; 298 } 299 300 public boolean contains(Object o) 301 { 302 List idList = getIdList(); 303 304 if(!relatedLocalInterface.isInstance(o)) 305 { 306 throw new IllegalArgumentException ("Object must be an instance of " + 307 relatedLocalInterface.getName()); 308 } 309 310 Object id = getPrimaryKey((EJBLocalObject ) o); 311 return idList.contains(id); 312 } 313 314 public boolean containsAll(Collection c) 315 { 316 List idList = getIdList(); 317 318 if(c == null) 319 { 320 return true; 321 } 322 323 List argIds = new ArrayList (); 325 Iterator iterator = c.iterator(); 326 while(iterator.hasNext()) 327 { 328 EJBLocalObject localObject = (EJBLocalObject ) iterator.next(); 329 Object relatedId = getPrimaryKey(localObject); 330 argIds.add(relatedId); 331 } 332 333 return idList.containsAll(argIds); 334 } 335 336 public Object [] toArray(Object a[]) 337 { 338 List idList = getIdList(); 339 340 Collection c = cmrField.getRelatedInvoker().getEntityLocalCollection(idList); 341 return c.toArray(a); 342 } 343 344 public Object [] toArray() 345 { 346 List idList = getIdList(); 347 Collection c = cmrField.getRelatedInvoker().getEntityLocalCollection(idList); 348 return c.toArray(); 349 } 350 351 353 private static void checkForPKChange() 354 { 355 366 } 367 368 370 public Iterator iterator() 371 { 372 return new Iterator () 373 { 374 private final Iterator idIterator = getIdList().iterator(); 375 private final LocalProxyFactory localFactory = cmrField.getRelatedInvoker(); 376 private Object currentId; 377 378 public boolean hasNext() 379 { 380 verifyIteratorIsValid(); 381 382 try 383 { 384 return idIterator.hasNext(); 385 } 386 catch(ConcurrentModificationException e) 387 { 388 throw new IllegalStateException ("Underlying collection has " + 389 "been modified"); 390 } 391 } 392 393 public Object next() 394 { 395 verifyIteratorIsValid(); 396 397 try 398 { 399 currentId = idIterator.next(); 400 return localFactory.getEntityEJBLocalObject(currentId); 401 } 402 catch(ConcurrentModificationException e) 403 { 404 throw new IllegalStateException ("Underlying collection has " + 405 "been modified"); 406 } 407 } 408 409 public void remove() 410 { 411 verifyIteratorIsValid(); 412 if(readOnly) 413 { 414 throw new EJBException ("This collection is a read-only snapshot"); 415 } 416 if(cmrField.isReadOnly()) 417 { 418 throw new EJBException ("Field is read-only: " + 419 cmrField.getFieldName()); 420 } 421 422 checkForPKChange(); 423 424 try 425 { 426 idIterator.remove(); 427 cmrField.destroyRelationLinks(ctx, currentId, false); 428 } 429 catch(ConcurrentModificationException e) 430 { 431 throw new IllegalStateException ("Underlying collection has been modified"); 432 } 433 } 434 435 private void verifyIteratorIsValid() 436 { 437 if(setHandle[0] == null) 438 { 439 throw new IllegalStateException ("The iterator of a CMR " + 440 "collection may only be used within the transction in " + 441 "which it was created"); 442 } 443 } 444 }; 445 } 446 447 public String toString() 448 { 449 return new StringBuffer () 450 .append('[') 451 .append(cmrField.getEntity().getEntityName()) 452 .append('.') 453 .append(cmrField.getFieldName()) 454 .append(':') 455 .append(getIdList()).append(']') 456 .toString(); 457 } 458 459 private Object getPrimaryKey(EJBLocalObject o) 460 { 461 try 462 { 463 return o.getPrimaryKey(); 464 } 465 catch(NoSuchObjectLocalException e) 466 { 467 throw new IllegalArgumentException (e.getMessage()); 468 } 469 } 470 } 471 | Popular Tags |