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