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