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.common.CollectionDiff; 17 import com.versant.core.common.VersantFieldMetaData; 18 import com.versant.core.common.PersistenceContext; 19 20 import javax.jdo.spi.PersistenceCapable; 21 import java.util.HashMap ; 22 import java.util.Hashtable ; 23 import java.util.Iterator ; 24 import java.util.Map ; 25 26 import com.versant.core.jdo.VersantPersistenceManagerImp; 27 import com.versant.core.jdo.VersantStateManager; 28 29 public class SCOHashtable extends Hashtable implements VersantSCOMap, VersantAdvancedSCO { 30 31 private transient PersistenceCapable owner; 32 private transient VersantStateManager stateManager; 33 private final transient VersantFieldMetaData fmd; 34 private transient MapDiffUtil diffUtil; 35 private transient Map beforeMap = new HashMap (); 36 37 private SCOHashtable(PersistenceCapable owner, 38 VersantFieldMetaData fmd) { 39 this.owner = owner; 40 this.fmd = fmd; 41 diffUtil = new MapDiffUtil(fmd); 42 } 43 44 public SCOHashtable(PersistenceCapable owner, VersantStateManager stateManager, 45 VersantFieldMetaData fmd, Map beforeMap) { 46 this(owner, fmd); 47 if (!owner.jdoIsNew()) { 48 this.beforeMap.putAll(beforeMap); 49 } 50 putAll(beforeMap); 51 this.stateManager = stateManager; 52 } 53 54 public SCOHashtable(PersistenceCapable owner, VersantStateManager stateManager, 55 VersantFieldMetaData fmd, MapData mapData) { 56 this(owner, fmd); 57 int n = mapData.entryCount; 58 Object [] keys = mapData.keys; 59 Object [] values = mapData.values; 60 for (int i = 0; i < n; i++) { 61 beforeMap.put(keys[i], values[i]); 62 } 63 putAll(beforeMap); 64 this.stateManager = stateManager; 65 } 66 67 public Object put(Object key, Object value) { 68 makeDirty(); 69 return super.put(key, value); 70 } 71 72 public Object remove(Object key) { 73 return checkModified(super.remove(key)); 74 } 75 76 public void putAll(Map t) { 77 makeDirty(); 78 super.putAll(t); 79 } 80 81 public void clear() { 82 final int size = size(); 83 super.clear(); 84 if (size != 0) makeDirty(); 85 } 86 87 public Object getOwner() { 88 return owner; 89 } 90 91 public void makeTransient() { 92 owner = null; 93 stateManager = null; 94 } 95 96 public void makeDirty() { 97 if (stateManager != null) { 98 stateManager.makeDirty(owner, fmd.getManagedFieldNo()); 99 } 100 } 101 102 public void reset() { 103 beforeMap.clear(); 104 beforeMap.putAll(this); 105 } 106 107 private Object checkModified(Object obj) { 108 if (obj != null) { 109 makeDirty(); 110 } 111 return obj; 112 } 113 114 public CollectionDiff getMapDiff(PersistenceContext pm) { 115 return diffUtil.getDiff(this, beforeMap, pm); 116 } 117 118 123 public MapData fillMapData(MapData mapData) { 124 int size = size(); 125 mapData.entryCount = size; 126 Object [] newKeys; 127 Object [] oldKeys = mapData.keys; 128 if (oldKeys == null || oldKeys.length < size) { 129 newKeys = new Object [size]; 130 } else { 131 newKeys = oldKeys; 132 } 133 Object [] newValues; 134 Object [] oldValues = mapData.values; 135 if (oldValues == null || oldValues.length < size) { 136 newValues = new Object [size]; 137 } else { 138 newValues = oldValues; 139 } 140 int i = 0; 141 for (Iterator it = this.entrySet().iterator(); it.hasNext();) { 142 Entry entry = (Entry) it.next(); 143 newKeys[i] = entry.getKey(); 144 newValues[i++] = entry.getValue(); 145 } 146 mapData.keys = newKeys; 147 mapData.values = newValues; 148 return mapData; 149 } 150 } 151 | Popular Tags |