1 2 12 package com.versant.core.jdo.sco; 13 14 import com.versant.core.jdo.VersantPersistenceManagerImp; 15 import com.versant.core.jdo.VersantStateManager; 16 import com.versant.core.jdo.VersantStateManager; 17 import com.versant.core.common.CollectionDiff; 18 import com.versant.core.common.VersantFieldMetaData; 19 20 import javax.jdo.spi.PersistenceCapable; 21 import java.util.Collection ; 22 import java.util.HashSet ; 23 import java.util.Iterator ; 24 25 import com.versant.core.common.BindingSupportImpl; 26 import com.versant.core.common.PersistenceContext; 27 28 33 public class SCOHashSet extends HashSet implements VersantManagedSCOCollection, VersantAdvancedSCO { 34 35 private transient PersistenceCapable owner; 36 private transient VersantStateManager stateManager; 37 private final transient VersantFieldMetaData fmd; 38 private final transient boolean isMaster; 39 private final transient boolean isMany; 40 private final transient int inverseFieldNo; 41 private transient Object [] originalData; 42 private boolean beenReset; 43 44 public SCOHashSet(PersistenceCapable owner, VersantStateManager stateManager, 45 VersantFieldMetaData fmd, Object [] originalData) { 46 this.isMaster = fmd.isManaged() && fmd.isMaster(); 47 this.inverseFieldNo = fmd.getInverseFieldNo(); 48 this.owner = owner; 49 this.stateManager = stateManager; 50 this.fmd = fmd; 51 this.isMany = fmd.isManaged() && fmd.isManyToMany(); 52 this.originalData = originalData; 53 int n = originalData == null ? 0 : originalData.length; 54 if (!owner.jdoIsNew()) { 55 for (int i = 0; i < n; i++) { 56 Object o = originalData[i]; 57 if (o == null) break; 58 super.add(o); 59 } 60 } else if (isMaster) { 61 for (int i = 0; i < n; i++) { 62 Object o = originalData[i]; 63 if (o == null) throw createNPE(); 64 super.add(o); 65 SCOInverseUtil.addMasterOnDetail(o, owner, inverseFieldNo); 66 } 67 } else if (isMany) { 68 for (int i = 0; i < n; i++) { 69 Object o = originalData[i]; 70 if (o == null) throw createNPE(); 71 super.add(o); 72 SCOInverseUtil.addToOtherSideOfManyToMany(o, inverseFieldNo, owner); 73 } 74 } else { 75 for (int i = 0; i < n; i++) { 76 Object o = originalData[i]; 77 if (o == null) throw createNPE(); 78 super.add(o); 79 } 80 } 81 } 82 83 private RuntimeException createNPE() { 84 return BindingSupportImpl.getInstance().nullElement("Null element not allowed: " + fmd.getQName()); 85 } 86 87 public boolean add(Object o) { 88 if (o == null) throw createNPE(); 89 if (isMaster) { 90 boolean result = super.add(o); 91 if (result) { 92 makeDirty(); 93 SCOInverseUtil.addMasterOnDetail(o, owner, inverseFieldNo); 94 } 95 return result; 96 } else if (isMany) { 97 boolean result = super.add(o); 98 if (result) { 99 makeDirty(); 100 SCOInverseUtil.addToOtherSideOfManyToMany(o, inverseFieldNo, owner); 101 } 102 return result; 103 } else { 104 boolean result = super.add(o); 105 if (result) makeDirty(); 106 return result; 107 } 108 } 109 110 public boolean remove(Object o) { 111 boolean result = super.remove(o); 112 if (result) { 113 makeDirty(); 114 if (isMaster) { 115 SCOInverseUtil.removeMasterOnDetail(o, owner, inverseFieldNo); 116 } else if (isMany) { 117 SCOInverseUtil.removeFromOtherSideOfManyToMany(o, inverseFieldNo, owner); 118 } 119 } 120 return result; 121 } 122 123 public void clear() { 124 if (isMaster) { 125 for (Iterator iter = super.iterator(); iter.hasNext();) { 126 SCOInverseUtil.removeMasterOnDetail(iter.next(), owner, inverseFieldNo); 127 } 128 } else if (isMany) { 129 for (Iterator iter = super.iterator(); iter.hasNext();) { 130 SCOInverseUtil.removeFromOtherSideOfManyToMany(iter.next(), inverseFieldNo, owner); 131 } 132 } 133 super.clear(); 134 makeDirty(); 135 } 136 137 public boolean retainAll(Collection c) { 138 if (isMaster) { 139 boolean modified = false; 140 Iterator e = super.iterator(); 141 while (e.hasNext()) { 142 Object o = e.next(); 143 if (!c.contains(o)) { 144 e.remove(); 145 SCOInverseUtil.removeMasterOnDetail(o, owner, inverseFieldNo); 146 modified = true; 147 } 148 } 149 if (modified) makeDirty(); 150 return modified; 151 } else if (isMany) { 152 boolean modified = false; 153 Iterator e = super.iterator(); 154 while (e.hasNext()) { 155 Object o = e.next(); 156 if (!c.contains(o)) { 157 e.remove(); 158 SCOInverseUtil.removeFromOtherSideOfManyToMany(o, inverseFieldNo, owner); 159 modified = true; 160 } 161 } 162 if (modified) makeDirty(); 163 return modified; 164 } else if (super.retainAll(c)) { 165 makeDirty(); 166 return true; 167 } 168 return false; 169 } 170 171 public boolean removeAll(Collection c) { 172 if (isMaster) { 173 boolean modified = false; 174 Object o = null; 175 if (size() > c.size()) { 176 for (Iterator i = c.iterator(); i.hasNext();) { 177 o = i.next(); 178 if (o != null) { 179 modified |= super.remove(o); 180 SCOInverseUtil.removeMasterOnDetail(o, owner, inverseFieldNo); 181 } 182 } 183 } else { 184 for (Iterator i = super.iterator(); i.hasNext();) { 185 o = i.next(); 186 if (c.contains(o)) { 187 i.remove(); 188 modified = true; 189 SCOInverseUtil.removeMasterOnDetail(o, owner, inverseFieldNo); 190 } 191 } 192 } 193 if (modified) makeDirty(); 194 return modified; 195 } else if (isMany) { 196 boolean modified = false; 197 Object o = null; 198 if (size() > c.size()) { 199 for (Iterator i = c.iterator(); i.hasNext();) { 200 o = i.next(); 201 if (o != null) { 202 boolean ans = super.remove(o); 203 if (ans) { 204 modified = true; 205 SCOInverseUtil.removeFromOtherSideOfManyToMany(o, inverseFieldNo, owner); 206 } 207 } 208 } 209 } else { 210 for (Iterator i = super.iterator(); i.hasNext();) { 211 o = i.next(); 212 if (c.contains(o)) { 213 i.remove(); 214 modified = true; 215 SCOInverseUtil.removeFromOtherSideOfManyToMany(o, inverseFieldNo, owner); 216 } 217 } 218 } 219 if (modified) makeDirty(); 220 return modified; 221 } else if (super.removeAll(c)) { 222 makeDirty(); 223 return true; 224 } 225 return false; 226 } 227 228 public boolean addAll(Collection c) { 229 if (isMaster) { 230 boolean modified = false; 231 Object o = null; 232 Iterator e = c.iterator(); 233 while (e.hasNext()) { 234 o = e.next(); 235 if (o == null) { 236 throw createNPE(); 237 } else if (super.add(o)) { 238 modified = true; 239 SCOInverseUtil.addMasterOnDetail(o, owner, inverseFieldNo); 240 } 241 } 242 if (modified) makeDirty(); 243 return modified; 244 } else if (isMany) { 245 boolean modified = false; 246 Object o = null; 247 Iterator e = c.iterator(); 248 while (e.hasNext()) { 249 o = e.next(); 250 if (o == null) { 251 throw createNPE(); 252 } else if (super.add(o)) { 253 modified = true; 254 SCOInverseUtil.addToOtherSideOfManyToMany(o, inverseFieldNo, owner); 255 } 256 } 257 if (modified) makeDirty(); 258 return modified; 259 } else if (super.addAll(c)) { 260 makeDirty(); 261 return true; 262 } 263 return false; 264 265 } 266 267 public Iterator iterator() { 268 return new SCOIterator(super.iterator(), stateManager, owner, fmd.getManagedFieldNo()); 269 } 270 271 public Object getOwner() { 272 return owner; 273 } 274 275 public void makeTransient() { 276 owner = null; 277 stateManager = null; 278 } 279 280 public void makeDirty() { 281 if (stateManager != null) { 282 stateManager.makeDirty(owner, fmd.getManagedFieldNo()); 283 } 284 } 285 286 public void reset() { 287 beenReset = true; 288 originalData = toArray(); 289 } 290 291 public CollectionDiff getCollectionDiff(PersistenceContext pm) { 292 Object [] data = toArray(); 293 return CollectionDiffUtil.getUnorderedCollectionDiff(fmd, pm, 294 data, data.length, (owner.jdoIsNew() && !beenReset) ? null : originalData); 295 } 296 297 public void manyToManyAdd(Object o) { 298 if (super.add(o)) makeDirty(); 299 } 300 301 public void manyToManyRemove(Object o) { 302 if (super.remove(o)) makeDirty(); 303 } 304 305 308 public boolean isOrdered() { 309 return fmd.isOrdered(); 310 } 311 312 317 public CollectionData fillCollectionData(CollectionData collectionData) { 318 int size = size(); 319 collectionData.valueCount = size; 320 Object [] newData; 321 Object [] values = collectionData.values; 322 if (values == null || values.length < size) { 323 newData = new Object [size]; 324 } else { 325 newData = values; 326 } 327 int i = 0; 328 for (Iterator it = this.iterator(); it.hasNext();) { 329 newData[i++] = it.next(); 330 } 331 collectionData.values = newData; 332 return collectionData; 333 } 334 } 335 | Popular Tags |