1 19 20 package org.apache.cayenne; 21 22 import java.io.ObjectStreamException ; 23 import java.io.Serializable ; 24 import java.util.AbstractList ; 25 import java.util.ArrayList ; 26 import java.util.Collections ; 27 import java.util.HashMap ; 28 import java.util.Iterator ; 29 import java.util.List ; 30 import java.util.Map ; 31 32 import org.apache.cayenne.graph.ArcCreateOperation; 33 import org.apache.cayenne.graph.ArcDeleteOperation; 34 import org.apache.cayenne.graph.CompoundDiff; 35 import org.apache.cayenne.graph.GraphDiff; 36 import org.apache.cayenne.graph.NodeDiff; 37 38 45 class ObjectContextChangeLog { 46 47 List diffs; 48 Map markers; 49 50 ObjectContextChangeLog() { 51 reset(); 52 } 53 54 void unregisterNode(Object nodeId) { 55 Iterator it = diffs.iterator(); 56 while (it.hasNext()) { 57 Object next = it.next(); 58 59 if (next instanceof NodeDiff) { 60 61 if (nodeId.equals(((NodeDiff) next).getNodeId())) { 62 it.remove(); 63 } 64 else if (next instanceof ArcCreateOperation) { 65 if (nodeId.equals(((ArcCreateOperation) next).getTargetNodeId())) { 66 it.remove(); 67 } 68 } 69 else if (next instanceof ArcDeleteOperation) { 70 if (nodeId.equals(((ArcDeleteOperation) next).getTargetNodeId())) { 71 it.remove(); 72 } 73 } 74 } 75 } 76 } 77 78 void setMarker(String markerTag) { 79 markers.put(markerTag, new Integer (diffs.size())); 80 } 81 82 void removeMarker(String markerTag) { 83 markers.remove(markerTag); 84 } 85 86 89 GraphDiff getDiffs() { 90 return new CompoundDiff(immutableList(0, diffs.size())); 91 } 92 93 GraphDiff getDiffsAfterMarker(String markerTag) { 94 Integer pos = (Integer ) markers.get(markerTag); 95 int marker = (pos == null) ? -1 : pos.intValue(); 96 if (marker < 0) { 97 throw new IllegalStateException ("No marked position for tag '" 98 + markerTag 99 + "'"); 100 } 101 102 return new CompoundDiff(immutableList(marker, diffs.size())); 103 } 104 105 boolean hasMarker(String markerTag) { 106 return markers.containsKey(markerTag); 107 } 108 109 112 void reset() { 113 this.diffs = new ArrayList (); 117 this.markers = new HashMap (); 118 } 119 120 int size() { 121 return diffs.size(); 122 } 123 124 int sizeAfterMarker(String markerTag) { 125 Integer pos = (Integer ) markers.get(markerTag); 126 int marker = (pos == null) ? -1 : pos.intValue(); 127 if (marker < 0) { 128 throw new IllegalStateException ("No marked position for tag '" 129 + markerTag 130 + "'"); 131 } 132 133 return diffs.size() - marker; 134 } 135 136 139 void addOperation(GraphDiff diff) { 140 diffs.add(diff); 141 } 142 143 147 private List immutableList(int fromIndex, int toIndex) { 148 if (toIndex - fromIndex == 0) { 149 return Collections.EMPTY_LIST; 150 } 151 152 return Collections.unmodifiableList(new SubList(diffs, fromIndex, toIndex)); 155 } 156 157 static class SubList extends AbstractList implements Serializable { 160 161 private List list; 162 private int offset; 163 private int size; 164 165 SubList(List list, int fromIndex, int toIndex) { 166 if (fromIndex < 0) 167 throw new IndexOutOfBoundsException ("fromIndex = " + fromIndex); 168 if (toIndex > list.size()) { 169 throw new IndexOutOfBoundsException ("toIndex = " + toIndex); 170 } 171 if (fromIndex > toIndex) { 172 throw new IllegalArgumentException ("fromIndex(" 173 + fromIndex 174 + ") > toIndex(" 175 + toIndex 176 + ")"); 177 } 178 this.list = list; 179 offset = fromIndex; 180 size = toIndex - fromIndex; 181 } 182 183 public Object get(int index) { 184 rangeCheck(index); 185 return list.get(index + offset); 186 } 187 188 public int size() { 189 return size; 190 } 191 192 private void rangeCheck(int index) { 193 if (index < 0 || index >= size) { 194 throw new IndexOutOfBoundsException ("Index: " + index + ",Size: " + size); 195 } 196 } 197 198 private Object writeReplace() throws ObjectStreamException { 200 return new ArrayList (list.subList(offset, offset + size)); 201 } 202 } 203 204 } 205 | Popular Tags |