|
16 | 16 | import io.ably.lib.http.HttpUtils; |
17 | 17 | import io.ably.lib.objects.RealtimeObjects; |
18 | 18 | import io.ably.lib.objects.LiveObjectsPlugin; |
| 19 | +import io.ably.lib.rest.MessageEditsMixin; |
19 | 20 | import io.ably.lib.rest.RestAnnotations; |
20 | 21 | import io.ably.lib.transport.ConnectionManager; |
21 | 22 | import io.ably.lib.transport.ConnectionManager.QueuedMessage; |
|
32 | 33 | import io.ably.lib.types.Message; |
33 | 34 | import io.ably.lib.types.MessageAnnotations; |
34 | 35 | import io.ably.lib.types.MessageDecodeException; |
| 36 | +import io.ably.lib.types.MessageOperation; |
35 | 37 | import io.ably.lib.types.MessageSerializer; |
36 | 38 | import io.ably.lib.types.MessageVersion; |
37 | 39 | import io.ably.lib.types.PaginatedResult; |
@@ -100,6 +102,8 @@ public abstract class ChannelBase extends EventEmitter<ChannelEvent, ChannelStat |
100 | 102 |
|
101 | 103 | @Nullable private final LiveObjectsPlugin liveObjectsPlugin; |
102 | 104 |
|
| 105 | + private volatile MessageEditsMixin messageEditsMixin; |
| 106 | + |
103 | 107 | public RealtimeObjects getObjects() throws AblyException { |
104 | 108 | if (liveObjectsPlugin == null) { |
105 | 109 | throw AblyException.fromErrorInfo( |
@@ -1172,6 +1176,172 @@ else if(!"false".equalsIgnoreCase(param.value)) { |
1172 | 1176 | private static final String KEY_UNTIL_ATTACH = "untilAttach"; |
1173 | 1177 | private static final String KEY_FROM_SERIAL = "fromSerial"; |
1174 | 1178 |
|
| 1179 | + //region Message Edits and Deletes |
| 1180 | + |
| 1181 | + /** |
| 1182 | + * Retrieves the latest version of a specific message by its serial identifier. |
| 1183 | + * <p> |
| 1184 | + * This method allows you to fetch the current state of a message, including any updates |
| 1185 | + * or deletions that have been applied since its creation. |
| 1186 | + * |
| 1187 | + * @param serial The unique serial identifier of the message to retrieve. |
| 1188 | + * @return A {@link Message} object representing the latest version of the message. |
| 1189 | + * @throws AblyException If the message cannot be retrieved or does not exist. |
| 1190 | + */ |
| 1191 | + public Message getMessage(String serial) throws AblyException { |
| 1192 | + return messageEditsMixin.getMessage(ably.http, serial); |
| 1193 | + } |
| 1194 | + |
| 1195 | + /** |
| 1196 | + * Asynchronously retrieves the latest version of a specific message by its serial identifier. |
| 1197 | + * |
| 1198 | + * @param serial The unique serial identifier of the message to retrieve. |
| 1199 | + * @param callback A callback to handle the result asynchronously. |
| 1200 | + * <p> |
| 1201 | + * This callback is invoked on a background thread. |
| 1202 | + */ |
| 1203 | + public void getMessageAsync(String serial, Callback<Message> callback) { |
| 1204 | + messageEditsMixin.getMessageAsync(ably.http, serial, callback); |
| 1205 | + } |
| 1206 | + |
| 1207 | + /** |
| 1208 | + * Updates an existing message using patch semantics. |
| 1209 | + * <p> |
| 1210 | + * Non-null fields in the provided message (name, data, extras) will replace the corresponding |
| 1211 | + * fields in the existing message, while null fields will be left unchanged. |
| 1212 | + * |
| 1213 | + * @param message A {@link Message} object containing the fields to update and the serial identifier. |
| 1214 | + * Only non-null fields will be applied to the existing message. |
| 1215 | + * @param operation operation metadata such as clientId, description, or metadata in the version field |
| 1216 | + * @throws AblyException If the update operation fails. |
| 1217 | + */ |
| 1218 | + public void updateMessage(Message message, MessageOperation operation) throws AblyException { |
| 1219 | + messageEditsMixin.updateMessage(ably.http, message, operation); |
| 1220 | + } |
| 1221 | + |
| 1222 | + /** |
| 1223 | + * Updates an existing message using patch semantics. |
| 1224 | + * <p> |
| 1225 | + * Non-null fields in the provided message (name, data, extras) will replace the corresponding |
| 1226 | + * fields in the existing message, while null fields will be left unchanged. |
| 1227 | + * |
| 1228 | + * @param message A {@link Message} object containing the fields to update and the serial identifier. |
| 1229 | + * Only non-null fields will be applied to the existing message. |
| 1230 | + * @throws AblyException If the update operation fails. |
| 1231 | + */ |
| 1232 | + public void updateMessage(Message message) throws AblyException { |
| 1233 | + updateMessage(message, null); |
| 1234 | + } |
| 1235 | + |
| 1236 | + /** |
| 1237 | + * Asynchronously updates an existing message. |
| 1238 | + * |
| 1239 | + * @param message A {@link Message} object containing the fields to update and the serial identifier. |
| 1240 | + * @param operation operation metadata such as clientId, description, or metadata in the version field |
| 1241 | + * @param listener A listener to be notified of the outcome of this operation. |
| 1242 | + * <p> |
| 1243 | + * This listener is invoked on a background thread. |
| 1244 | + */ |
| 1245 | + public void updateMessageAsync(Message message, MessageOperation operation, CompletionListener listener) { |
| 1246 | + messageEditsMixin.updateMessageAsync(ably.http, message, operation, listener); |
| 1247 | + } |
| 1248 | + |
| 1249 | + /** |
| 1250 | + * Asynchronously updates an existing message. |
| 1251 | + * |
| 1252 | + * @param message A {@link Message} object containing the fields to update and the serial identifier. |
| 1253 | + * @param listener A listener to be notified of the outcome of this operation. |
| 1254 | + * <p> |
| 1255 | + * This listener is invoked on a background thread. |
| 1256 | + */ |
| 1257 | + public void updateMessageAsync(Message message, CompletionListener listener) { |
| 1258 | + updateMessageAsync(message, null, listener); |
| 1259 | + } |
| 1260 | + |
| 1261 | + /** |
| 1262 | + * Marks a message as deleted. |
| 1263 | + * <p> |
| 1264 | + * This operation does not remove the message from history; it marks it as deleted |
| 1265 | + * while preserving the full message history. The deleted message can still be |
| 1266 | + * retrieved and will have its action set to MESSAGE_DELETE. |
| 1267 | + * |
| 1268 | + * @param message A {@link Message} message containing the serial identifier. |
| 1269 | + * @param operation operation metadata such as clientId, description, or metadata in the version field |
| 1270 | + * @throws AblyException If the delete operation fails. |
| 1271 | + */ |
| 1272 | + public void deleteMessage(Message message, MessageOperation operation) throws AblyException { |
| 1273 | + messageEditsMixin.deleteMessage(ably.http, message, operation); |
| 1274 | + } |
| 1275 | + |
| 1276 | + /** |
| 1277 | + * Marks a message as deleted. |
| 1278 | + * <p> |
| 1279 | + * This operation does not remove the message from history; it marks it as deleted |
| 1280 | + * while preserving the full message history. The deleted message can still be |
| 1281 | + * retrieved and will have its action set to MESSAGE_DELETE. |
| 1282 | + * |
| 1283 | + * @param message A {@link Message} message containing the serial identifier. |
| 1284 | + * @throws AblyException If the delete operation fails. |
| 1285 | + */ |
| 1286 | + public void deleteMessage(Message message) throws AblyException { |
| 1287 | + deleteMessage(message, null); |
| 1288 | + } |
| 1289 | + |
| 1290 | + /** |
| 1291 | + * Asynchronously marks a message as deleted. |
| 1292 | + * |
| 1293 | + * @param message A {@link Message} object containing the serial identifier and operation metadata. |
| 1294 | + * @param operation operation metadata such as clientId, description, or metadata in the version field |
| 1295 | + * @param listener A listener to be notified of the outcome of this operation. |
| 1296 | + * <p> |
| 1297 | + * This listener is invoked on a background thread. |
| 1298 | + */ |
| 1299 | + public void deleteMessageAsync(Message message, MessageOperation operation, CompletionListener listener) { |
| 1300 | + messageEditsMixin.deleteMessageAsync(ably.http, message, operation, listener); |
| 1301 | + } |
| 1302 | + |
| 1303 | + /** |
| 1304 | + * Asynchronously marks a message as deleted. |
| 1305 | + * |
| 1306 | + * @param message A {@link Message} object containing the serial identifier and operation metadata. |
| 1307 | + * @param listener A listener to be notified of the outcome of this operation. |
| 1308 | + * <p> |
| 1309 | + * This listener is invoked on a background thread. |
| 1310 | + */ |
| 1311 | + public void deleteMessageAsync(Message message, CompletionListener listener) { |
| 1312 | + deleteMessageAsync(message, null, listener); |
| 1313 | + } |
| 1314 | + |
| 1315 | + /** |
| 1316 | + * Retrieves all historical versions of a specific message. |
| 1317 | + * <p> |
| 1318 | + * This method returns a paginated result containing all versions of the message, |
| 1319 | + * ordered chronologically. Each version includes metadata about when and by whom |
| 1320 | + * the message was modified. |
| 1321 | + * |
| 1322 | + * @param serial The unique serial identifier of the message. |
| 1323 | + * @param params Query parameters for filtering or pagination (e.g., limit, start, end). |
| 1324 | + * @return A {@link PaginatedResult} containing an array of {@link Message} objects |
| 1325 | + * representing all versions of the message. |
| 1326 | + * @throws AblyException If the versions cannot be retrieved. |
| 1327 | + */ |
| 1328 | + public PaginatedResult<Message> getMessageVersions(String serial, Param[] params) throws AblyException { |
| 1329 | + return messageEditsMixin.getMessageVersions(ably.http, serial, params); |
| 1330 | + } |
| 1331 | + |
| 1332 | + /** |
| 1333 | + * Asynchronously retrieves all historical versions of a specific message. |
| 1334 | + * |
| 1335 | + * @param serial The unique serial identifier of the message. |
| 1336 | + * @param params Query parameters for filtering or pagination. |
| 1337 | + * @param callback A callback to handle the result asynchronously. |
| 1338 | + */ |
| 1339 | + public void getMessageVersionsAsync(String serial, Param[] params, Callback<AsyncPaginatedResult<Message>> callback) throws AblyException { |
| 1340 | + messageEditsMixin.getMessageVersionsAsync(ably.http, serial, params, callback); |
| 1341 | + } |
| 1342 | + |
| 1343 | + //endregion |
| 1344 | + |
1175 | 1345 | /************************************ |
1176 | 1346 | * Channel history |
1177 | 1347 | ************************************/ |
@@ -1278,6 +1448,7 @@ public void setOptions(ChannelOptions options) throws AblyException { |
1278 | 1448 | */ |
1279 | 1449 | public void setOptions(ChannelOptions options, CompletionListener listener) throws AblyException { |
1280 | 1450 | this.options = options; |
| 1451 | + this.messageEditsMixin = new MessageEditsMixin(basePath, ably.options, options, ably.auth); |
1281 | 1452 | if(this.shouldReattachToSetOptions(options)) { |
1282 | 1453 | this.attach(true, listener); |
1283 | 1454 | } else { |
@@ -1353,6 +1524,7 @@ else if(stateChange.current.equals(failureState)) { |
1353 | 1524 | this, |
1354 | 1525 | new RestAnnotations(name, ably.http, ably.options, options) |
1355 | 1526 | ); |
| 1527 | + this.messageEditsMixin = new MessageEditsMixin(basePath, ably.options, options, ably.auth); |
1356 | 1528 | } |
1357 | 1529 |
|
1358 | 1530 | void onChannelMessage(ProtocolMessage msg) { |
|
0 commit comments