Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions lib/src/main/java/io/ably/lib/objects/Adapter.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
import io.ably.lib.realtime.AblyRealtime;
import io.ably.lib.realtime.ChannelState;
import io.ably.lib.realtime.CompletionListener;
import io.ably.lib.transport.ConnectionManager;
import io.ably.lib.types.AblyException;
import io.ably.lib.types.ChannelMode;
import io.ably.lib.types.ChannelOptions;
import io.ably.lib.types.ClientOptions;
import io.ably.lib.types.ProtocolMessage;
import io.ably.lib.util.Log;
import org.jetbrains.annotations.NotNull;
Expand Down Expand Up @@ -65,4 +67,19 @@ public ChannelState getChannelState(@NotNull String channelName) {
Log.e(TAG, "getChannelState(): channel not found: " + channelName);
return null;
}

@Override
public @NotNull ClientOptions getClientOptions() {
return ably.options;
}

@Override
public @NotNull ConnectionManager getConnectionManager() {
return ably.connection.connectionManager;
}

@Override
public long getTime() throws AblyException {
return ably.time();
}
}
71 changes: 42 additions & 29 deletions lib/src/main/java/io/ably/lib/objects/LiveObjects.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
import io.ably.lib.objects.state.ObjectsStateChange;
import io.ably.lib.objects.type.counter.LiveCounter;
import io.ably.lib.objects.type.map.LiveMap;
import io.ably.lib.objects.type.map.LiveMapValue;
import org.jetbrains.annotations.Blocking;
import org.jetbrains.annotations.NonBlocking;
import org.jetbrains.annotations.NotNull;


import java.util.Map;

/**
Expand All @@ -33,46 +33,60 @@ public interface LiveObjects extends ObjectsStateChange {
LiveMap getRoot();

/**
* Creates a new LiveMap based on an existing LiveMap.
* Creates a new empty LiveMap with no entries.
* Send a MAP_CREATE operation to the realtime system to create a new map object in the pool.
* Once the ACK message is received, the method returns the object from the local pool if it got created due to
* the echoed MAP_CREATE operation, or if it wasn't received yet, the method creates a new object locally
* using the provided data and returns it.
* and returns it.
*
* @param liveMap the existing LiveMap to base the new LiveMap on.
* @return the newly created LiveMap instance.
* @return the newly created empty LiveMap instance.
*/
@Blocking
@NotNull
LiveMap createMap(@NotNull LiveMap liveMap);
LiveMap createMap();

/**
* Creates a new LiveMap based on a LiveCounter.
* Creates a new LiveMap with type-safe entries that can be Boolean, Binary, Number, String, JsonArray, JsonObject, LiveCounter, or LiveMap.
* Implements spec RTO11 : createMap(Dict<String, Boolean | Binary | Number | String | JsonArray | JsonObject | LiveCounter | LiveMap> entries?)
* Send a MAP_CREATE operation to the realtime system to create a new map object in the pool.
* Once the ACK message is received, the method returns the object from the local pool if it got created due to
* the echoed MAP_CREATE operation, or if it wasn't received yet, the method creates a new object locally
* using the provided data and returns it.
*
* @param liveCounter the LiveCounter to base the new LiveMap on.
* <h3>Example:</h3>
* <pre>{@code
* Map<String, LiveMapValue> entries = Map.of(
* "string", LiveMapValue.of("Hello"),
* "number", LiveMapValue.of(42),
* "boolean", LiveMapValue.of(true),
* "binary", LiveMapValue.of(new byte[]{1, 2, 3}),
* "array", LiveMapValue.of(new JsonArray()),
* "object", LiveMapValue.of(new JsonObject()),
* "counter", LiveMapValue.of(liveObjects.createCounter()),
* "nested", LiveMapValue.of(liveObjects.createMap())
* );
* LiveMap map = liveObjects.createMap(entries);
* }</pre>
*
* @param entries the type-safe map entries with values that can be Boolean, Binary, Number, String, JsonArray, JsonObject, LiveCounter, or LiveMap.
* @return the newly created LiveMap instance.
*/
@Blocking
@NotNull
LiveMap createMap(@NotNull LiveCounter liveCounter);
LiveMap createMap(@NotNull Map<String, LiveMapValue> entries);

/**
* Creates a new LiveMap based on a standard Java Map.
* Send a MAP_CREATE operation to the realtime system to create a new map object in the pool.
* Creates a new LiveCounter with an initial value of 0.
* Send a COUNTER_CREATE operation to the realtime system to create a new counter object in the pool.
* Once the ACK message is received, the method returns the object from the local pool if it got created due to
* the echoed MAP_CREATE operation, or if it wasn't received yet, the method creates a new object locally
* the echoed COUNTER_CREATE operation, or if it wasn't received yet, the method creates a new object locally
* using the provided data and returns it.
*
* @param map the Java Map to base the new LiveMap on.
* @return the newly created LiveMap instance.
* @return the newly created LiveCounter instance with initial value of 0.
*/
@Blocking
@NotNull
LiveMap createMap(@NotNull Map<String, Object> map);
LiveCounter createCounter();

/**
* Creates a new LiveCounter with an initial value.
Expand All @@ -86,7 +100,7 @@ public interface LiveObjects extends ObjectsStateChange {
*/
@Blocking
@NotNull
LiveCounter createCounter(@NotNull Long initialValue);
LiveCounter createCounter(@NotNull Number initialValue);

/**
* Asynchronously retrieves the root LiveMap object.
Expand All @@ -100,43 +114,42 @@ public interface LiveObjects extends ObjectsStateChange {
void getRootAsync(@NotNull ObjectsCallback<@NotNull LiveMap> callback);

/**
* Asynchronously creates a new LiveMap based on an existing LiveMap.
* Asynchronously creates a new empty LiveMap with no entries.
* Send a MAP_CREATE operation to the realtime system to create a new map object in the pool.
* Once the ACK message is received, the method returns the object from the local pool if it got created due to
* the echoed MAP_CREATE operation, or if it wasn't received yet, the method creates a new object locally
* using the provided data and returns it.
* and returns it.
*
* @param liveMap the existing LiveMap to base the new LiveMap on.
* @param callback the callback to handle the result or error.
*/
@NonBlocking
void createMapAsync(@NotNull LiveMap liveMap, @NotNull ObjectsCallback<@NotNull LiveMap> callback);
void createMapAsync(@NotNull ObjectsCallback<@NotNull LiveMap> callback);

/**
* Asynchronously creates a new LiveMap based on a LiveCounter.
* Asynchronously creates a new LiveMap with type-safe entries that can be Boolean, Binary, Number, String, JsonArray, JsonObject, LiveCounter, or LiveMap.
* This method implements the spec RTO11 signature: createMap(Dict<String, Boolean | Binary | Number | String | JsonArray | JsonObject | LiveCounter | LiveMap> entries?)
* Send a MAP_CREATE operation to the realtime system to create a new map object in the pool.
* Once the ACK message is received, the method returns the object from the local pool if it got created due to
* the echoed MAP_CREATE operation, or if it wasn't received yet, the method creates a new object locally
* using the provided data and returns it.
*
* @param liveCounter the LiveCounter to base the new LiveMap on.
* @param entries the type-safe map entries with values that can be Boolean, Binary, Number, String, JsonArray, JsonObject, LiveCounter, or LiveMap.
* @param callback the callback to handle the result or error.
*/
@NonBlocking
void createMapAsync(@NotNull LiveCounter liveCounter, @NotNull ObjectsCallback<@NotNull LiveMap> callback);
void createMapAsync(@NotNull Map<String, LiveMapValue> entries, @NotNull ObjectsCallback<@NotNull LiveMap> callback);

/**
* Asynchronously creates a new LiveMap based on a standard Java Map.
* Send a MAP_CREATE operation to the realtime system to create a new map object in the pool.
* Asynchronously creates a new LiveCounter with an initial value of 0.
* Send a COUNTER_CREATE operation to the realtime system to create a new counter object in the pool.
* Once the ACK message is received, the method returns the object from the local pool if it got created due to
* the echoed MAP_CREATE operation, or if it wasn't received yet, the method creates a new object locally
* the echoed COUNTER_CREATE operation, or if it wasn't received yet, the method creates a new object locally
* using the provided data and returns it.
*
* @param map the Java Map to base the new LiveMap on.
* @param callback the callback to handle the result or error.
*/
@NonBlocking
void createMapAsync(@NotNull Map<String, Object> map, @NotNull ObjectsCallback<@NotNull LiveMap> callback);
void createCounterAsync(@NotNull ObjectsCallback<@NotNull LiveCounter> callback);

/**
* Asynchronously creates a new LiveCounter with an initial value.
Expand All @@ -149,5 +162,5 @@ public interface LiveObjects extends ObjectsStateChange {
* @param callback the callback to handle the result or error.
*/
@NonBlocking
void createCounterAsync(@NotNull Long initialValue, @NotNull ObjectsCallback<@NotNull LiveCounter> callback);
void createCounterAsync(@NotNull Number initialValue, @NotNull ObjectsCallback<@NotNull LiveCounter> callback);
}
28 changes: 28 additions & 0 deletions lib/src/main/java/io/ably/lib/objects/LiveObjectsAdapter.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@

import io.ably.lib.realtime.ChannelState;
import io.ably.lib.realtime.CompletionListener;
import io.ably.lib.transport.ConnectionManager;
import io.ably.lib.types.AblyException;
import io.ably.lib.types.ChannelMode;
import io.ably.lib.types.ClientOptions;
import io.ably.lib.types.ProtocolMessage;
import org.jetbrains.annotations.Blocking;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

Expand Down Expand Up @@ -53,5 +56,30 @@ public interface LiveObjectsAdapter {
* @return the current state of the specified channel, or null if the channel is not found
*/
@Nullable ChannelState getChannelState(@NotNull String channelName);

/**
* Retrieves the client options configured for the Ably client.
* Used to access client configuration parameters such as echoMessages setting
* that affect the behavior of LiveObjects operations.
*
* @return the client options containing configuration parameters
*/
@NotNull ClientOptions getClientOptions();

/**
* Retrieves the connection manager for handling connection state and operations.
* Used to check connection status, obtain error information, and manage
* message transmission across the Ably connection.
*
* @return the connection manager instance
*/
@NotNull ConnectionManager getConnectionManager();

/**
* Retrieves the current time in milliseconds from the Ably server.
* Spec: RTO16
*/
@Blocking
long getTime() throws AblyException;
}

40 changes: 25 additions & 15 deletions lib/src/main/java/io/ably/lib/objects/type/counter/LiveCounter.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,47 +14,57 @@
public interface LiveCounter extends LiveCounterChange {

/**
* Increments the value of the counter by 1.
* Increments the value of the counter by the specified amount.
* Send a COUNTER_INC operation to the realtime system to increment a value on this LiveCounter object.
* This does not modify the underlying data of this LiveCounter object. Instead, the change will be applied when
* the published COUNTER_INC operation is echoed back to the client and applied to the object following the regular
* operation application procedure.
* Spec: RTLC12
*
* @param amount the amount by which to increment the counter
*/
@Blocking
void increment(@NotNull Number amount);

/**
* Decrements the value of the counter by the specified amount.
* An alias for calling {@link LiveCounter#increment(Number)} with a negative amount.
* Spec: RTLC13
*
* @param amount the amount by which to decrement the counter
*/
@Blocking
void increment();
void decrement(@NotNull Number amount);

/**
* Increments the value of the counter by 1 asynchronously.
* Increments the value of the counter by the specified amount asynchronously.
* Send a COUNTER_INC operation to the realtime system to increment a value on this LiveCounter object.
* This does not modify the underlying data of this LiveCounter object. Instead, the change will be applied when
* the published COUNTER_INC operation is echoed back to the client and applied to the object following the regular
* operation application procedure.
* Spec: RTLC12
*
* @param amount the amount by which to increment the counter
* @param callback the callback to be invoked upon completion of the operation.
*/
@NonBlocking
void incrementAsync(@NotNull ObjectsCallback<Void> callback);

/**
* Decrements the value of the counter by 1.
* An alias for calling {@link LiveCounter#increment()} with a negative amount.
*/
@Blocking
void decrement();
void incrementAsync(@NotNull Number amount, @NotNull ObjectsCallback<Void> callback);

/**
* Decrements the value of the counter by 1 asynchronously.
* An alias for calling {@link LiveCounter#increment()} with a negative amount.
* Decrements the value of the counter by the specified amount asynchronously.
* An alias for calling {@link LiveCounter#incrementAsync(Number, ObjectsCallback)} with a negative amount.
* Spec: RTLC13
*
* @param amount the amount by which to decrement the counter
* @param callback the callback to be invoked upon completion of the operation.
*/
@NonBlocking
void decrementAsync(@NotNull ObjectsCallback<Void> callback);
void decrementAsync(@NotNull Number amount, @NotNull ObjectsCallback<Void> callback);

/**
* Retrieves the current value of the counter.
*
* @return the current value of the counter as a Long.
* @return the current value of the counter as a Double.
*/
@NotNull
@Contract(pure = true) // Indicates this method does not modify the state of the object.
Expand Down
14 changes: 9 additions & 5 deletions lib/src/main/java/io/ably/lib/objects/type/map/LiveMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public interface LiveMap extends LiveMapChange {
* @return the value associated with the specified key, or null if the key does not exist.
*/
@Nullable
Object get(@NotNull String keyName);
LiveMapValue get(@NotNull String keyName);

/**
* Retrieves all entries (key-value pairs) in the map.
Expand All @@ -40,7 +40,7 @@ public interface LiveMap extends LiveMapChange {
*/
@NotNull
@Unmodifiable
Iterable<Map.Entry<String, Object>> entries();
Iterable<Map.Entry<String, LiveMapValue>> entries();

/**
* Retrieves all keys in the map.
Expand All @@ -60,27 +60,29 @@ public interface LiveMap extends LiveMapChange {
*/
@NotNull
@Unmodifiable
Iterable<Object> values();
Iterable<LiveMapValue> values();

/**
* Sets the specified key to the given value in the map.
* Send a MAP_SET operation to the realtime system to set a key on this LiveMap object to a specified value.
* This does not modify the underlying data of this LiveMap object. Instead, the change will be applied when
* the published MAP_SET operation is echoed back to the client and applied to the object following the regular
* operation application procedure.
* Spec: RTLM20
*
* @param keyName the key to be set.
* @param value the value to be associated with the key.
*/
@Blocking
void set(@NotNull String keyName, @NotNull Object value);
void set(@NotNull String keyName, @NotNull LiveMapValue value);

/**
* Removes the specified key and its associated value from the map.
* Send a MAP_REMOVE operation to the realtime system to tombstone a key on this LiveMap object.
* This does not modify the underlying data of this LiveMap object. Instead, the change will be applied when
* the published MAP_REMOVE operation is echoed back to the client and applied to the object following the regular
* operation application procedure.
* Spec: RTLM21
*
* @param keyName the key to be removed.
*/
Expand All @@ -103,20 +105,22 @@ public interface LiveMap extends LiveMapChange {
* This does not modify the underlying data of this LiveMap object. Instead, the change will be applied when
* the published MAP_SET operation is echoed back to the client and applied to the object following the regular
* operation application procedure.
* Spec: RTLM20
*
* @param keyName the key to be set.
* @param value the value to be associated with the key.
* @param callback the callback to handle the result or any errors.
*/
@NonBlocking
void setAsync(@NotNull String keyName, @NotNull Object value, @NotNull ObjectsCallback<Void> callback);
void setAsync(@NotNull String keyName, @NotNull LiveMapValue value, @NotNull ObjectsCallback<Void> callback);

/**
* Asynchronously removes the specified key and its associated value from the map.
* Send a MAP_REMOVE operation to the realtime system to tombstone a key on this LiveMap object.
* This does not modify the underlying data of this LiveMap object. Instead, the change will be applied when
* the published MAP_REMOVE operation is echoed back to the client and applied to the object following the regular
* operation application procedure.
* Spec: RTLM21
*
* @param keyName the key to be removed.
* @param callback the callback to handle the result or any errors.
Expand Down
Loading
Loading