Skip to content

Commit 19d3ef0

Browse files
authored
Merge pull request #1059 from ably/feature/message-edits-and-deletes
[ECO-5193] Support message edits and deletes
2 parents 6f8fa54 + c3264ea commit 19d3ef0

File tree

4 files changed

+864
-7
lines changed

4 files changed

+864
-7
lines changed

lib/src/main/java/io/ably/lib/types/Message.java

Lines changed: 151 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
import java.io.IOException;
44
import java.lang.reflect.Type;
55
import java.util.Collection;
6+
import java.util.HashMap;
7+
import java.util.Map;
8+
69
import com.google.gson.JsonArray;
710
import com.google.gson.JsonDeserializer;
811
import com.google.gson.JsonDeserializationContext;
@@ -74,13 +77,110 @@ public class Message extends BaseMessage {
7477
*/
7578
public Long createdAt;
7679

80+
/**
81+
* (TM2l) ref string – an opaque string that uniquely identifies some referenced message.
82+
*/
83+
public String refSerial;
84+
85+
/**
86+
* (TM2m) refType string – an opaque string that identifies the type of this reference.
87+
*/
88+
public String refType;
89+
90+
/**
91+
* (TM2n) operation object – data object that may contain the `optional` attributes.
92+
*/
93+
public Operation operation;
94+
95+
public static class Operation {
96+
public String clientId;
97+
public String description;
98+
public Map<String, String> metadata;
99+
100+
void write(MessagePacker packer) throws IOException {
101+
int fieldCount = 0;
102+
if (clientId != null) fieldCount++;
103+
if (description != null) fieldCount++;
104+
if (metadata != null) fieldCount++;
105+
106+
packer.packMapHeader(fieldCount);
107+
108+
if (clientId != null) {
109+
packer.packString("clientId");
110+
packer.packString(clientId);
111+
}
112+
if (description != null) {
113+
packer.packString("description");
114+
packer.packString(description);
115+
}
116+
if (metadata != null) {
117+
packer.packString("metadata");
118+
packer.packMapHeader(metadata.size());
119+
for (Map.Entry<String, String> entry : metadata.entrySet()) {
120+
packer.packString(entry.getKey());
121+
packer.packString(entry.getValue());
122+
}
123+
}
124+
}
125+
126+
protected static Operation read(final MessageUnpacker unpacker) throws IOException {
127+
Operation operation = new Operation();
128+
int fieldCount = unpacker.unpackMapHeader();
129+
for (int i = 0; i < fieldCount; i++) {
130+
String fieldName = unpacker.unpackString().intern();
131+
switch (fieldName) {
132+
case "clientId":
133+
operation.clientId = unpacker.unpackString();
134+
break;
135+
case "description":
136+
operation.description = unpacker.unpackString();
137+
break;
138+
case "metadata":
139+
int mapSize = unpacker.unpackMapHeader();
140+
operation.metadata = new HashMap<>(mapSize);
141+
for (int j = 0; j < mapSize; j++) {
142+
String key = unpacker.unpackString();
143+
String value = unpacker.unpackString();
144+
operation.metadata.put(key, value);
145+
}
146+
break;
147+
default:
148+
unpacker.skipValue();
149+
break;
150+
}
151+
}
152+
return operation;
153+
}
154+
155+
protected static Operation read(final JsonObject jsonObject) throws MessageDecodeException {
156+
Operation operation = new Operation();
157+
if (jsonObject.has("clientId")) {
158+
operation.clientId = jsonObject.get("clientId").getAsString();
159+
}
160+
if (jsonObject.has("description")) {
161+
operation.description = jsonObject.get("description").getAsString();
162+
}
163+
if (jsonObject.has("metadata")) {
164+
JsonObject metadataObject = jsonObject.getAsJsonObject("metadata");
165+
operation.metadata = new HashMap<>();
166+
for (Map.Entry<String, JsonElement> entry : metadataObject.entrySet()) {
167+
operation.metadata.put(entry.getKey(), entry.getValue().getAsString());
168+
}
169+
}
170+
return operation;
171+
}
172+
}
173+
77174
private static final String NAME = "name";
78175
private static final String EXTRAS = "extras";
79176
private static final String CONNECTION_KEY = "connectionKey";
80177
private static final String SERIAL = "serial";
81178
private static final String VERSION = "version";
82179
private static final String ACTION = "action";
83180
private static final String CREATED_AT = "createdAt";
181+
private static final String REF_SERIAL = "refSerial";
182+
private static final String REF_TYPE = "refType";
183+
private static final String OPERATION = "operation";
84184

85185
/**
86186
* Default constructor
@@ -160,10 +260,15 @@ void writeMsgpack(MessagePacker packer) throws IOException {
160260
int fieldCount = super.countFields();
161261
if(name != null) ++fieldCount;
162262
if(extras != null) ++fieldCount;
263+
if(connectionKey != null) ++fieldCount;
163264
if(serial != null) ++fieldCount;
164265
if(version != null) ++fieldCount;
165266
if(action != null) ++fieldCount;
166267
if(createdAt != null) ++fieldCount;
268+
if(refSerial != null) ++fieldCount;
269+
if(refType != null) ++fieldCount;
270+
if(operation != null) ++fieldCount;
271+
167272
packer.packMapHeader(fieldCount);
168273
super.writeFields(packer);
169274
if(name != null) {
@@ -174,6 +279,10 @@ void writeMsgpack(MessagePacker packer) throws IOException {
174279
packer.packString(EXTRAS);
175280
extras.write(packer);
176281
}
282+
if(connectionKey != null) {
283+
packer.packString(CONNECTION_KEY);
284+
packer.packString(connectionKey);
285+
}
177286
if(serial != null) {
178287
packer.packString(SERIAL);
179288
packer.packString(serial);
@@ -190,6 +299,18 @@ void writeMsgpack(MessagePacker packer) throws IOException {
190299
packer.packString(CREATED_AT);
191300
packer.packLong(createdAt);
192301
}
302+
if(refSerial != null) {
303+
packer.packString(REF_SERIAL);
304+
packer.packString(refSerial);
305+
}
306+
if(refType != null) {
307+
packer.packString(REF_TYPE);
308+
packer.packString(refType);
309+
}
310+
if(operation != null) {
311+
packer.packString(OPERATION);
312+
operation.write(packer);
313+
}
193314
}
194315

195316
Message readMsgpack(MessageUnpacker unpacker) throws IOException {
@@ -209,6 +330,8 @@ Message readMsgpack(MessageUnpacker unpacker) throws IOException {
209330
name = unpacker.unpackString();
210331
} else if (fieldName.equals(EXTRAS)) {
211332
extras = MessageExtras.read(unpacker);
333+
} else if (fieldName.equals(CONNECTION_KEY)) {
334+
connectionKey = unpacker.unpackString();
212335
} else if (fieldName.equals(SERIAL)) {
213336
serial = unpacker.unpackString();
214337
} else if (fieldName.equals(VERSION)) {
@@ -217,7 +340,14 @@ Message readMsgpack(MessageUnpacker unpacker) throws IOException {
217340
action = MessageAction.tryFindByOrdinal(unpacker.unpackInt());
218341
} else if (fieldName.equals(CREATED_AT)) {
219342
createdAt = unpacker.unpackLong();
220-
} else {
343+
} else if (fieldName.equals(REF_SERIAL)) {
344+
refSerial = unpacker.unpackString();
345+
} else if (fieldName.equals(REF_TYPE)) {
346+
refType = unpacker.unpackString();
347+
} else if (fieldName.equals(OPERATION)) {
348+
operation = Operation.read(unpacker);
349+
}
350+
else {
221351
Log.v(TAG, "Unexpected field: " + fieldName);
222352
unpacker.skipValue();
223353
}
@@ -373,12 +503,23 @@ protected void read(final JsonObject map) throws MessageDecodeException {
373503
}
374504
extras = MessageExtras.read((JsonObject) extrasElement);
375505
}
506+
connectionKey = readString(map, CONNECTION_KEY);
376507

377508
serial = readString(map, SERIAL);
378509
version = readString(map, VERSION);
379510
Integer actionOrdinal = readInt(map, ACTION);
380511
action = actionOrdinal == null ? null : MessageAction.tryFindByOrdinal(actionOrdinal);
381512
createdAt = readLong(map, CREATED_AT);
513+
refSerial = readString(map, REF_SERIAL);
514+
refType = readString(map, REF_TYPE);
515+
516+
final JsonElement operationElement = map.get(OPERATION);
517+
if (null != operationElement) {
518+
if (!(operationElement instanceof JsonObject)) {
519+
throw MessageDecodeException.fromDescription("Message operation is of type \"" + operationElement.getClass() + "\" when expected a JSON object.");
520+
}
521+
operation = Operation.read((JsonObject) operationElement);
522+
}
382523
}
383524

384525
public static class Serializer implements JsonSerializer<Message>, JsonDeserializer<Message> {
@@ -406,6 +547,15 @@ public JsonElement serialize(Message message, Type typeOfMessage, JsonSerializat
406547
if (message.createdAt != null) {
407548
json.addProperty(CREATED_AT, message.createdAt);
408549
}
550+
if (message.refSerial != null) {
551+
json.addProperty(REF_SERIAL, message.refSerial);
552+
}
553+
if (message.refType != null) {
554+
json.addProperty(REF_TYPE, message.refType);
555+
}
556+
if (message.operation != null) {
557+
json.add(OPERATION, Serialisation.gson.toJsonTree(message.operation));
558+
}
409559
return json;
410560
}
411561

0 commit comments

Comments
 (0)