001: /*
002: * All content copyright (c) 2003-2007 Terracotta, Inc., except as may otherwise be noted in a separate copyright
003: * notice. All rights reserved.
004: */
005: package com.tc.l2.msg;
006:
007: import com.tc.async.api.OrderedEventContext;
008: import com.tc.bytes.TCByteBuffer;
009: import com.tc.io.TCByteBufferInputStream;
010: import com.tc.net.groups.AbstractGroupMessage;
011: import com.tc.object.ObjectID;
012: import com.tc.object.dna.impl.ObjectDNAImpl;
013: import com.tc.object.dna.impl.ObjectStringSerializer;
014: import com.tc.util.Assert;
015:
016: import java.io.IOException;
017: import java.io.ObjectInput;
018: import java.io.ObjectOutput;
019: import java.util.ArrayList;
020: import java.util.Collections;
021: import java.util.HashMap;
022: import java.util.HashSet;
023: import java.util.Iterator;
024: import java.util.List;
025: import java.util.Map;
026: import java.util.Set;
027: import java.util.Map.Entry;
028:
029: public class ObjectSyncMessage extends AbstractGroupMessage implements
030: OrderedEventContext {
031:
032: public static final int MANAGED_OBJECT_SYNC_TYPE = 0;
033:
034: private Set oids;
035: private int dnaCount;
036: private TCByteBuffer[] dnas;
037: private ObjectStringSerializer serializer;
038: private Map rootsMap;
039: private long sequenceID;
040:
041: public ObjectSyncMessage() {
042: // Make serialization happy
043: super (-1);
044: }
045:
046: public ObjectSyncMessage(int type) {
047: super (type);
048: }
049:
050: protected void basicReadExternal(int msgType, ObjectInput in)
051: throws IOException {
052: Assert.assertEquals(MANAGED_OBJECT_SYNC_TYPE, msgType);
053: oids = readObjectIDS(in, new HashSet(500));
054: dnaCount = in.readInt();
055: readRootsMap(in);
056: serializer = readObjectStringSerializer(in);
057: this .dnas = readByteBuffers(in);
058: this .sequenceID = in.readLong();
059: }
060:
061: protected void basicWriteExternal(int msgType, ObjectOutput out)
062: throws IOException {
063: Assert.assertEquals(MANAGED_OBJECT_SYNC_TYPE, msgType);
064: writeObjectIDS(out, oids);
065: out.writeInt(dnaCount);
066: writeRootsMap(out);
067: writeObjectStringSerializer(out, serializer);
068: writeByteBuffers(out, dnas);
069: recycle(dnas);
070: dnas = null;
071: out.writeLong(this .sequenceID);
072: }
073:
074: private void writeRootsMap(ObjectOutput out) throws IOException {
075: out.writeInt(rootsMap.size());
076: for (Iterator i = rootsMap.entrySet().iterator(); i.hasNext();) {
077: Entry e = (Entry) i.next();
078: out.writeUTF((String) e.getKey());
079: out.writeLong(((ObjectID) e.getValue()).toLong());
080: }
081: }
082:
083: private void readRootsMap(ObjectInput in) throws IOException {
084: int size = in.readInt();
085: if (size == 0) {
086: this .rootsMap = Collections.EMPTY_MAP;
087: } else {
088: this .rootsMap = new HashMap(size);
089: for (int i = 0; i < size; i++) {
090: this .rootsMap.put(in.readUTF(), new ObjectID(in
091: .readLong()));
092: }
093: }
094: }
095:
096: private void recycle(TCByteBuffer[] buffers) {
097: for (int i = 0; i < buffers.length; i++) {
098: buffers[i].recycle();
099: }
100: }
101:
102: public void initialize(Set dnaOids, int count,
103: TCByteBuffer[] serializedDNAs,
104: ObjectStringSerializer objectSerializer, Map roots, long sID) {
105: this .oids = dnaOids;
106: this .dnaCount = count;
107: this .dnas = serializedDNAs;
108: this .serializer = objectSerializer;
109: this .rootsMap = roots;
110: this .sequenceID = sID;
111: }
112:
113: public int getDnaCount() {
114: return dnaCount;
115: }
116:
117: public Set getOids() {
118: return oids;
119: }
120:
121: public Map getRootsMap() {
122: return rootsMap;
123: }
124:
125: /**
126: * This method calls returns a list of DNAs that can be applied to ManagedObjects. This method could only be called
127: * once. It throws an AssertionError if you ever call this twice
128: */
129: public List getDNAs() {
130: Assert.assertNotNull(this .dnas);
131: TCByteBufferInputStream toi = new TCByteBufferInputStream(
132: this .dnas);
133: ArrayList objectDNAs = new ArrayList(dnaCount);
134: for (int i = 0; i < dnaCount; i++) {
135: ObjectDNAImpl dna = new ObjectDNAImpl(serializer, false);
136: try {
137: dna.deserializeFrom(toi);
138: } catch (IOException e) {
139: throw new AssertionError(e);
140: }
141: Assert.assertFalse(dna.isDelta());
142: objectDNAs.add(dna);
143: }
144: this .dnas = null;
145: return objectDNAs;
146: }
147:
148: /*
149: * For testing only
150: */
151: public TCByteBuffer[] getUnprocessedDNAs() {
152: TCByteBuffer[] tcbb = new TCByteBuffer[dnas.length];
153: for (int i = 0; i < dnas.length; i++) {
154: tcbb[i] = dnas[i];
155: }
156: return tcbb;
157: }
158:
159: public long getSequenceID() {
160: return this.sequenceID;
161: }
162: }
|