001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
003: */
004: package com.tc.objectserver.managedobject;
005:
006: import com.tc.object.ObjectID;
007: import com.tc.object.SerializationUtil;
008: import com.tc.object.dna.api.DNACursor;
009: import com.tc.object.dna.api.DNAWriter;
010: import com.tc.object.dna.api.LogicalAction;
011: import com.tc.objectserver.mgmt.LogicalManagedObjectFacade;
012: import com.tc.objectserver.mgmt.ManagedObjectFacade;
013:
014: import java.io.IOException;
015: import java.io.ObjectInput;
016: import java.io.ObjectOutput;
017: import java.util.ArrayList;
018: import java.util.Iterator;
019: import java.util.Set;
020:
021: /**
022: * Server representation of a list
023: */
024: public class ListManagedObjectState extends LogicalManagedObjectState {
025: private ArrayList references;
026:
027: ListManagedObjectState(ObjectInput in) throws IOException {
028: super (in);
029: }
030:
031: protected ListManagedObjectState(long classID) {
032: super (classID);
033: references = new ArrayList(1);
034: }
035:
036: public void apply(ObjectID objectID, DNACursor cursor,
037: BackReferences includeIDs) throws IOException {
038: while (cursor.next()) {
039: LogicalAction action = cursor.getLogicalAction();
040: int method = action.getMethod();
041: Object[] params = action.getParameters();
042:
043: switch (method) {
044: case SerializationUtil.ADD:
045: case SerializationUtil.ADD_LAST:
046: addChangeToCollector(objectID, params[0], includeIDs);
047: references.add(params[0]);
048: break;
049: case SerializationUtil.ADD_FIRST:
050: addChangeToCollector(objectID, params[0], includeIDs);
051: references.add(0, params[0]);
052: break;
053: case SerializationUtil.INSERT_AT:
054: case SerializationUtil.ADD_AT:
055: addChangeToCollector(objectID, params[1], includeIDs);
056: int ai = Math.min(((Integer) params[0]).intValue(),
057: references.size());
058: if (references.size() < ai) {
059: references.add(params[1]);
060: } else {
061: references.add(ai, params[1]);
062: }
063: break;
064: case SerializationUtil.REMOVE:
065: references.remove(params[0]);
066: break;
067: case SerializationUtil.REMOVE_AT:
068: int index = ((Integer) params[0]).intValue();
069: if (references.size() > index) {
070: references.remove(index);
071: }
072: break;
073: case SerializationUtil.REMOVE_RANGE: {
074: int size = references.size();
075: int fromIndex = ((Integer) params[0]).intValue();
076: int toIndex = ((Integer) params[1]).intValue();
077: int removeIndex = fromIndex;
078: if (size > fromIndex && size >= toIndex) {
079: while (fromIndex++ < toIndex) {
080: references.remove(removeIndex);
081: }
082: }
083: }
084: break;
085: case SerializationUtil.CLEAR:
086: references.clear();
087: break;
088: case SerializationUtil.SET_ELEMENT:
089: case SerializationUtil.SET:
090: addChangeToCollector(objectID, params[1], includeIDs);
091: int si = Math.min(((Integer) params[0]).intValue(),
092: references.size());
093: if (references.size() <= si) {
094: references.add(params[1]);
095: } else {
096: references.set(si, params[1]);
097: }
098: break;
099: case SerializationUtil.REMOVE_FIRST:
100: if (references.size() > 0) {
101: references.remove(0);
102: }
103: break;
104: case SerializationUtil.REMOVE_LAST:
105: int size = references.size();
106: if (size > 0) {
107: references.remove(size - 1);
108: }
109: break;
110: case SerializationUtil.SET_SIZE:
111: int setSize = ((Integer) params[0]).intValue();
112: int listSize = references.size();
113:
114: if (listSize < setSize) {
115: for (int i = listSize; i < setSize; i++) {
116: references.add(ObjectID.NULL_ID);
117: }
118: } else if (listSize > setSize) {
119: for (int i = listSize; i != setSize; i--) {
120: references.remove(i - 1);
121: }
122: }
123: break;
124: case SerializationUtil.TRIM_TO_SIZE:
125: // do nothing for now
126: break;
127: default:
128: throw new AssertionError("Invalid method:" + method
129: + " state:" + this );
130: }
131: }
132: }
133:
134: private void addChangeToCollector(ObjectID objectID,
135: Object newValue, BackReferences includeIDs) {
136: if (newValue instanceof ObjectID) {
137: getListener().changed(objectID, null, (ObjectID) newValue);
138: includeIDs.addBackReference((ObjectID) newValue, objectID);
139: }
140: }
141:
142: protected void addAllObjectReferencesTo(Set refs) {
143: addAllObjectReferencesFromIteratorTo(references.iterator(),
144: refs);
145: }
146:
147: public void dehydrate(ObjectID objectID, DNAWriter writer) {
148: for (Iterator i = references.iterator(); i.hasNext();) {
149: Object value = i.next();
150: writer.addLogicalAction(SerializationUtil.ADD,
151: new Object[] { value });
152: }
153: }
154:
155: public String toString() {
156: return "ListManagedStateObject(" + references + ")";
157: }
158:
159: public ManagedObjectFacade createFacade(ObjectID objectID,
160: String className, int limit) {
161: final int size = references.size();
162:
163: if (limit < 0) {
164: limit = size;
165: } else {
166: limit = Math.min(limit, size);
167: }
168:
169: Object[] data = new Object[limit];
170:
171: int index = 0;
172: for (Iterator iter = references.iterator(); iter.hasNext()
173: && index < limit; index++) {
174: data[index] = iter.next();
175: }
176:
177: return LogicalManagedObjectFacade.createListInstance(objectID,
178: className, data, size);
179: }
180:
181: public byte getType() {
182: return LIST_TYPE;
183: }
184:
185: protected void basicWriteTo(ObjectOutput out) throws IOException {
186: out.writeInt(references.size());
187: for (Iterator i = references.iterator(); i.hasNext();) {
188: out.writeObject(i.next());
189: }
190: }
191:
192: protected boolean basicEquals(LogicalManagedObjectState o) {
193: ListManagedObjectState mo = (ListManagedObjectState) o;
194: return references.equals(mo.references);
195: }
196:
197: static ListManagedObjectState readFrom(ObjectInput in)
198: throws IOException, ClassNotFoundException {
199: ListManagedObjectState listmo = new ListManagedObjectState(in);
200: int size = in.readInt();
201: ArrayList list = new ArrayList(size);
202: for (int i = 0; i < size; i++) {
203: list.add(in.readObject());
204: }
205: listmo.references = list;
206: return listmo;
207: }
208:
209: }
|