1 18 package org.objectweb.speedo.genclass.map; 19 20 import java.util.ArrayList ; 21 import java.util.Collection ; 22 import java.util.Collections ; 23 import java.util.HashMap ; 24 import java.util.HashSet ; 25 import java.util.Iterator ; 26 import java.util.Map ; 27 import java.util.Set ; 28 29 import javax.jdo.PersistenceManager; 30 31 import org.objectweb.jorm.api.PExceptionIO; 32 import org.objectweb.jorm.api.PIndexedElem; 33 import org.objectweb.jorm.naming.api.PName; 34 import org.objectweb.speedo.api.Debug; 35 import org.objectweb.speedo.genclass.GenClassAccessor; 36 import org.objectweb.speedo.genclass.GenClassElement; 37 import org.objectweb.speedo.genclass.SpeedoGenClassHome; 38 import org.objectweb.speedo.genclass.api.SpeedoGenClassProxy; 39 import org.objectweb.speedo.metadata.SpeedoFetchGroup; 40 import org.objectweb.speedo.mim.api.DetachedLifeCycle; 41 import org.objectweb.speedo.mim.api.LifeCycle; 42 import org.objectweb.speedo.mim.api.SpeedoAccessor; 43 import org.objectweb.speedo.mim.api.SpeedoProxy; 44 import org.objectweb.speedo.pm.api.ProxyManager; 45 import org.objectweb.util.monolog.api.BasicLevel; 46 47 public class MapAccessor 48 extends GenClassAccessor 49 implements Map { 50 51 55 protected Map map = null; 56 57 60 public MapAccessor(SpeedoGenClassProxy _jdoProxy) { 61 super(_jdoProxy); 62 this.elements = new ArrayList (); 63 this.map = (Map ) jdoProxy.createGenClass(); 64 } 65 66 public void makePersistent(ProxyManager pm) { 67 if (Debug.ON && getLogger() != null) { 68 logger.log(BasicLevel.DEBUG, "makePersistent"); 69 } 70 if (elements.size() > 0) { 71 ((SpeedoGenClassHome) getSpeedoProxy().getSpeedoHome()) 72 .makePersistent(pm, values().iterator(), null); 73 } 74 } 75 public void deletePersistent(ProxyManager pm) { 76 clear(); 77 } 78 79 public void setElements(Object o) { 80 clear(); 81 if (o != null) { 82 putAll(((Map ) o)); 83 } 84 } 85 86 public void loadFieldsFromAccessor(SpeedoAccessor sa) { 87 MapAccessor ma = (MapAccessor) sa; 88 map.clear(); 89 map.putAll(ma.map); 90 supportDelta = ma.supportDelta; 91 elements.clear(); 92 elements.addAll(ma.elements); 93 jdoSetStatus(ma.jdoGetStatus()); 94 } 95 96 public boolean speedoAdd(Object elemToAdd, Object hints) { 97 put(hints, elemToAdd, false); 98 return true; 99 } 100 101 public boolean speedoRemove(Object elemToRemove, Object hints) { 102 return remove(hints, false) != null; 103 } 104 105 public void detachCopy(ProxyManager pm, Map detachCtx, SpeedoAccessor fieldsClone, Collection fgHints){ 106 ((MapAccessor)fieldsClone).map = new HashMap (); 107 ((MapAccessor)fieldsClone).loadFieldsFromAccessor(this); 108 ((MapAccessor)fieldsClone).map.clear(); 110 boolean valueToFetch = false; 111 Collection fgHintsToSend = new ArrayList (); 112 synchronized(fgHints){ 113 Collection copyFgHints = new ArrayList (fgHints); 114 Iterator it2 = copyFgHints.iterator(); 115 while(it2.hasNext() && !valueToFetch){ 116 String s = (String ) it2.next(); 117 int idxValue = s.indexOf(SpeedoFetchGroup.FG_VALUE); 118 if(s.indexOf(SpeedoFetchGroup.FG_KEY) != -1) 119 fgHints.remove(s); 120 else if(idxValue != -1){ 121 valueToFetch = true; 122 fgHints.remove(s); 123 String add = s.substring(idxValue+SpeedoFetchGroup.FG_VALUE.length()); 124 if(add.length() > 0){ 125 fgHintsToSend.add(add); 126 } 127 } 128 } 129 } 130 Iterator it = ((GenClassAccessor) fieldsClone).elements.iterator(); 132 while(it.hasNext()){ 133 MapElem iElem = (MapElem) it.next(); 135 SpeedoProxy sp = (SpeedoProxy) iElem.getElement(pm); 137 Object key = iElem.getIndex(); 138 SpeedoProxy clone = null; 139 if(detachCtx != null) 140 clone = (SpeedoProxy) detachCtx.get(sp); 141 if(clone == null){ 142 synchronized(fgHints){ 143 if(valueToFetch){ 144 clone = (SpeedoProxy) pm.speedoDetachCopy(sp, detachCtx, fgHintsToSend); 146 } 147 } 148 } 149 ((MapAccessor)fieldsClone).map.put(key, clone); 151 } 152 ((GenClassAccessor) fieldsClone).jdoSetStatus(LifeCycle.TRANSIENT); 153 } 154 155 public void attachCopy(ProxyManager pm, Map attachCtx, SpeedoAccessor fieldsClone, boolean makeTransactional) { 156 MapAccessor ma = (MapAccessor) fieldsClone; 157 Iterator it = ma.map.entrySet().iterator(); 159 while(it.hasNext()){ 160 SpeedoProxy spDetached = (SpeedoProxy) it.next(); 162 SpeedoProxy sp = (SpeedoProxy) attachCtx.get(spDetached); 163 if(sp == null){ 164 attachCtx.put(spDetached, sp); 165 sp = (SpeedoProxy) pm.speedoAttachCopy(spDetached, makeTransactional, attachCtx); 166 } 167 175 } 176 } 177 178 public void refresh(ProxyManager pm, Map refreshCtx, Collection fgHints){ 179 commonRefreshRetrieve(pm, refreshCtx, fgHints, true); 180 } 181 182 public void retrieve(ProxyManager pm, Map retrieveCtx, Collection fgHints){ 183 commonRefreshRetrieve(pm, retrieveCtx, fgHints, false); 184 } 185 186 193 private void commonRefreshRetrieve(ProxyManager pm, Map ctx, Collection fgHints, boolean refresh){ 194 boolean valueToFetch = false; 195 Collection fgHintsToSend = new ArrayList (); 196 synchronized(fgHints){ 197 Collection copyFgHints = new ArrayList (fgHints); 198 Iterator it2 = copyFgHints.iterator(); 199 while(it2.hasNext() && !valueToFetch){ 200 String s = (String ) it2.next(); 201 int idxValue = s.indexOf(SpeedoFetchGroup.FG_VALUE); 202 if(s.indexOf(SpeedoFetchGroup.FG_KEY) != -1) 203 fgHints.remove(s); 204 else if(idxValue != -1){ 205 valueToFetch = true; 206 fgHints.remove(s); 207 String add = s.substring(idxValue+SpeedoFetchGroup.FG_VALUE.length()); 208 if(add.length() > 0){ 209 fgHintsToSend.add(add); 210 } 211 } 212 } 213 } 214 Iterator it = this.elements.iterator(); 216 while(it.hasNext()){ 217 MapElem iElem = (MapElem) it.next(); 219 SpeedoProxy sp = (SpeedoProxy) iElem.getElement(pm); 221 if(ctx != null && !ctx.containsKey(sp.getPName())){ 222 synchronized(fgHints){ 223 if(valueToFetch){ 224 if (refresh) { 225 pm.speedoRefresh(sp, ctx, fgHintsToSend); 227 } else { 228 pm.speedoRetrieve(sp, ctx, fgHintsToSend); 230 } 231 } 232 } 233 } 234 } 235 } 236 237 public Object put(Object key, Object value, boolean withCoherence) { 238 MapElem element = null; 239 Object res = map.get(key); 240 if(detachedStatus != DetachedLifeCycle.DETACHED_NONE) 241 return res; 242 if (res == null) { 243 element = (MapElem) createPIndexedElem(); 245 element.setIndex(key); 246 elements.add(element); 247 map.put(key, element); 248 } else { 249 element = (MapElem) res; 251 element.setStatus(PIndexedElem.ELEM_MODIFIED); 252 res = element.getElement(jdoProxy.jdoGetPersistenceManager()); 253 } 254 element.setElement(value); 255 256 if (value instanceof SpeedoProxy) { 257 ((SpeedoGenClassHome) getSpeedoProxy().getSpeedoHome()) 258 .makePersistent(null, (SpeedoProxy) value, 259 (SpeedoGenClassProxy) getSpeedoProxy()); 260 } 261 if (withCoherence) { 262 Object _o = value; 263 if (_o instanceof PName) { 264 _o = element.getElement(jdoProxy.jdoGetPersistenceManager()); 265 } 266 if (_o instanceof SpeedoProxy) { 267 jdoProxy.fireSpeedoElementAdded(_o); 268 } 269 } 270 return res; 271 } 272 273 public Object remove(Object key, boolean withCoherence) { 274 GenClassElement gcelem = (GenClassElement) map.get(key); 275 if (gcelem == null) { 276 return null; 277 } 278 gcelem.setStatus(PIndexedElem.ELEM_DELETED); 279 Object value = get(key); 280 map.remove(key); 281 if (withCoherence) { 282 Object _o = gcelem.getElement(jdoProxy.jdoGetPersistenceManager()); 283 if (_o != null) { 284 jdoProxy.fireSpeedoElementRemoved(_o); 285 } 286 } 287 return value; 288 } 289 290 294 public int size() { 295 return map.size(); 296 } 297 298 public boolean isEmpty() { 299 return map.isEmpty(); 300 } 301 302 public boolean containsKey(Object key) { 303 return map.containsKey(key); 304 } 305 306 public boolean containsValue(Object value) { 307 return false; 309 } 310 311 public Object get(Object key) { 312 Object value = map.get(key); 313 if (value == null) { 314 return null; 315 } else { 316 if(detachedStatus != DetachedLifeCycle.DETACHED_NONE) 318 return value; 319 else 320 return ((MapElem) value).getElement( 321 jdoProxy.jdoGetPersistenceManager()); 322 } 323 } 324 325 public Object put(Object key, Object value) { 326 return put(key, value, true); 327 } 328 329 public Object remove(Object key) { 330 return remove(key, true); 331 } 332 333 public void putAll(Map t) { 334 Iterator i = t.entrySet().iterator(); 335 while (i.hasNext()) { 336 Map.Entry entry = (Map.Entry ) i.next(); 337 put(entry.getKey(), entry.getValue()); 338 } 339 } 340 341 public void clear() { 342 Iterator i = elements.iterator(); 343 PersistenceManager pm = null; 344 while (i.hasNext()) { 345 GenClassElement gcelem = (GenClassElement) i.next(); 346 gcelem.setStatus(PIndexedElem.ELEM_DELETED); 347 if (pm == null) { 348 pm = jdoProxy.jdoGetPersistenceManager(); 349 } 350 Object _o = gcelem.getElement(pm); 351 if (_o != null) { 352 jdoProxy.fireSpeedoElementRemoved(_o); 353 } 354 } 355 map.clear(); 356 supportDelta = false; 357 } 358 359 public Set keySet() { 360 return Collections.unmodifiableSet(map.keySet()); 361 } 362 363 public Collection values() { 364 ArrayList res = new ArrayList (elements.size()); 365 for(int i=(elements.size()-1); i>=0; i--) { 366 MapElem me = (MapElem) elements.get(i); 367 if (me.getElemStatus() != PIndexedElem.ELEM_DELETED) { 368 res.add(me.getElement()); 369 } 370 } 371 return Collections.unmodifiableCollection(res); 372 } 373 374 public Set entrySet() { 375 Set res = new HashSet (elements.size()); 376 for(int i=(elements.size()-1); i>=0; i--) { 377 MapElem me = (MapElem) elements.get(i); 378 if (me.getElemStatus() != PIndexedElem.ELEM_DELETED) { 379 res.add(new MyMapEntry(me)); 380 } 381 } 382 return Collections.unmodifiableSet(res); 383 } 384 385 private class MyMapEntry implements Map.Entry { 386 MapElem me; 387 388 public MyMapEntry(MapElem _me) { 389 this.me = _me; 390 } 391 392 public Object getKey() { 393 return me.getIndex(); 394 } 395 396 public Object getValue() { 397 return me.getElement(); 398 } 399 400 public Object setValue(Object value) { 401 Object res = me.getElement(); 402 me.setStatus(PIndexedElem.ELEM_MODIFIED); 403 me.setElement(value); 404 return res; 405 } 406 } 407 408 public PIndexedElem createPIndexedElem(GenClassAccessor gca) { 412 return new MapElem(gca); 413 } 414 415 public void paAdd(PIndexedElem elem, Object conn) throws PExceptionIO { 416 GenClassElement gcelem = (GenClassElement) elem; 417 gcelem.setStatus(PIndexedElem.ELEM_UNMODIFIED); 419 elements.add(gcelem); 420 map.put(gcelem.getIndex(), gcelem); 421 } 422 423 public int paGetNbElem() { 424 return size(); 425 } 426 427 public Iterator paIterator() { 428 return elements.iterator(); 429 } 430 431 public void paSetNbElem(int nbelem) { 432 if (nbelem == -1) { 433 elements = new ArrayList (); 434 } else { 435 elements = new ArrayList (nbelem); 436 } 437 map = (Map ) jdoProxy.createGenClass(); 438 } 439 440 public void forceDetachedDirty() { 441 } 442 443 public void restoreDetachedNone() { 444 } 445 446 447 } 448 | Popular Tags |