diff --git a/src/main/java/io/github/hikingc/matrixsdk/api/Event.java b/src/main/java/io/github/hikingc/matrixsdk/api/Event.java
index f80486a..cec5af7 100644
--- a/src/main/java/io/github/hikingc/matrixsdk/api/Event.java
+++ b/src/main/java/io/github/hikingc/matrixsdk/api/Event.java
@@ -20,6 +20,10 @@
/// All operations in this interface are blocking. Implementations must ensure thread safety and
/// avoid synchronization blocks that cause carrier thread pinning during network I/O.
///
+/// Unless otherwise noted, every method in this interface throws [MatrixIOException] if the request
+/// or response payload cannot be processed, and [MatrixNetworkException] if the server's response
+/// status is not successful.
+///
/// @see Matrix Client-Server API
/// Specification for Events
public interface Event {
@@ -29,12 +33,16 @@ public interface Event {
/// @param roomId the room ID where the event is.
/// @param eventId the event ID to retrieve.
/// @return the full event.
+ /// @throws MatrixIOException when the payload cannot be processed.
+ /// @throws MatrixNetworkException when the response status is not successful.
ClientEvent getEvent(RoomID roomId, String eventId);
/// Returns currently-joined members
///
/// @param roomId the room ID to fetch data from.
/// @return a list of room members.
+ /// @throws MatrixIOException when the payload cannot be processed.
+ /// @throws MatrixNetworkException when the response status is not successful.
RoomMembers getJoinedMembers(RoomID roomId);
/// Returns a filterable list of members and their current membership state in a room.
@@ -47,14 +55,18 @@ public interface Event {
/// @param notMembership the kind of membership to exclude from the results. Defaults to no
/// filtering if unspecified.
/// @return a list of [ClientEvent]s with the membership information of room members.
+ /// @throws MatrixIOException when the payload cannot be processed.
+ /// @throws MatrixNetworkException when the response status is not successful.
List getMembers(
RoomID roomId, String at, Membership membership, Membership notMembership);
/// Get the state events for the current state of a room.
///
/// @param roomId the room ID to fetch data from.
- /// @return the current state of the room
- List> getStateEvents(RoomID roomId);
+ /// @return the current state of the room.
+ /// @throws MatrixIOException when the payload cannot be processed.
+ /// @throws MatrixNetworkException when the response status is not successful.
+ List> getStateEvents(RoomID roomId);
/// Looks up the contents of a state event in a room. If the user is joined to the room then the
/// state is taken from the current state of the room. If the user has left the room then the
@@ -64,6 +76,8 @@ List getMembers(
/// @param eventType the type of state to look up.
/// @param stateKey the room to look up the state in.
/// @return the content of the event, including all additional metadata fields.
+ /// @throws MatrixIOException when the payload cannot be processed.
+ /// @throws MatrixNetworkException when the response status is not successful.
@SuppressWarnings("java:S1452")
// Caller doesn't know content type ahead of time; polymorphic dispatch via @JsonTypeInfo resolves
// it
@@ -78,6 +92,7 @@ List getMembers(
/// @param dir the [ChronologicalDirection] in which to search
/// @return [Messages] with available data.
/// @throws MatrixIOException when the payload cannot be processed.
+ /// @throws MatrixNetworkException when the response status is not successful.
/// @throws NullPointerException when the roomId is null.
Messages getMessages(RoomID roomId, ChronologicalDirection dir, QueryParametersMessages params);
@@ -88,6 +103,8 @@ List getMembers(
/// @param dir the [ChronologicalDirection] in which to search
/// @param timestamp the timestamp to search from, as given in milliseconds since the Unix epoch.
/// @return [EventMetadata] if an event was found.
+ /// @throws MatrixIOException when the payload cannot be processed.
+ /// @throws MatrixNetworkException when the response status is not successful.
EventMetadata getEventClosestToTimestamp(
RoomID roomId, ChronologicalDirection dir, int timestamp);
@@ -96,6 +113,8 @@ EventMetadata getEventClosestToTimestamp(
///
/// @param roomId the room ID to fetch data from.
/// @return [RoomInfo] with current state of the room.
+ /// @throws MatrixIOException when the payload cannot be processed.
+ /// @throws MatrixNetworkException when the response status is not successful.
RoomInfo getInitialSync(RoomID roomId);
/// Sends a state event.
@@ -106,15 +125,19 @@ EventMetadata getEventClosestToTimestamp(
/// @return a [String] representing a unique identifier of the event.
/// @throws MatrixIOException when the payload cannot be processed.
/// @throws MatrixNetworkException when the response status is not successful.
+ /// @throws MatrixIOException when the payload cannot be processed.
+ /// @throws MatrixNetworkException when the response status is not successful.
String sendStateEvent(RoomID roomId, String stateKey, StateEventContent content);
/// Sends a message event.
///
- /// @param roomId the room ID where to send the event.
- /// @param txnId for this event. Clients should generate an ID unique across requests with the
+ /// @param roomId the room ID where to send the event.
+ /// @param txnId for this event. Clients should generate an ID unique across requests with the
/// same access token; it will be used by the server to ensure idempotency of requests.
/// @param content of any type of message event.
/// @return a [String] representing a unique identifier of the event.
+ /// @throws MatrixIOException when the payload cannot be processed.
+ /// @throws MatrixNetworkException when the response status is not successful.
String sendMessageEvent(RoomID roomId, String txnId, MessageEventContent content);
/// Strips all information out of an event which isn’t critical to the integrity of the
diff --git a/src/main/java/io/github/hikingc/matrixsdk/api/Filter.java b/src/main/java/io/github/hikingc/matrixsdk/api/Filter.java
index 4e498ce..f5a1279 100644
--- a/src/main/java/io/github/hikingc/matrixsdk/api/Filter.java
+++ b/src/main/java/io/github/hikingc/matrixsdk/api/Filter.java
@@ -2,12 +2,18 @@
import io.github.hikingc.matrixsdk.api.filters.FilterDefinition;
import io.github.hikingc.matrixsdk.api.identifiers.UserID;
+import io.github.hikingc.matrixsdk.exceptions.MatrixIOException;
+import io.github.hikingc.matrixsdk.exceptions.MatrixNetworkException;
/// Core interface for executing protocol operations for filtering.
///
/// All operations in this interface are blocking. Implementations must ensure thread safety and
/// avoid synchronization blocks that cause carrier thread pinning during network I/O.
///
+/// Unless otherwise noted, every method in this interface throws [MatrixIOException] if the request
+/// or response payload cannot be processed, and [MatrixNetworkException] if the server's response
+/// status is not successful.
+///
/// @see Matrix Client-Server API
/// Specification for Rooms
public interface Room {
@@ -24,8 +28,8 @@ public interface Room {
///
/// @param configuration of the room.
/// @return the created room’s ID.
- /// @throws MatrixIOException when the payload cannot be processed
- /// @throws MatrixNetworkException when the response status is not successful
+ /// @throws MatrixIOException when the payload cannot be processed.
+ /// @throws MatrixNetworkException when the response status is not successful.
String create(InitialRoomConfiguration configuration);
/// Requests the server to resolve a room alias if not possible, the server will use the
@@ -34,18 +38,24 @@ public interface Room {
/// @param roomAlias the room alias.
/// @return a [ResolvedAlias] containing the room ids for the requested alias and which servers
/// are aware of it.
+ /// @throws MatrixIOException when the payload cannot be processed.
+ /// @throws MatrixNetworkException when the response status is not successful.
ResolvedAlias resolveAlias(RoomAlias roomAlias);
/// Sets a room alias to a room.
///
/// @param roomAlias a [RoomAlias].
/// @param roomId the [RoomID] to receive the alias.
+ /// @throws MatrixIOException when the payload cannot be processed.
+ /// @throws MatrixNetworkException when the response status is not successful.
void setAlias(RoomAlias roomAlias, RoomID roomId);
/// Requests the server to remove a mapping of a room alias to a room id. On success, servers
/// might modify `m.room.canonical_alias`
///
/// @param roomAlias the [RoomAlias] to remove.
+ /// @throws MatrixIOException when the payload cannot be processed.
+ /// @throws MatrixNetworkException when the response status is not successful.
void deleteAlias(RoomAlias roomAlias);
/// Requests a list of aliases maintained by the local server for the given room, requires to be
@@ -56,12 +66,16 @@ public interface Room {
///
/// @param roomId the [RoomID] to find local aliases of.
/// @return a [List] of Room aliases.
+ /// @throws MatrixIOException when the payload cannot be processed.
+ /// @throws MatrixNetworkException when the response status is not successful.
List getAliasesOfARoom(RoomID roomId);
/// Requests the server to retrieve a list of the user's current rooms (in simple terms whoever
/// calls this method).
///
/// @return a [List] of the rooms.
+ /// @throws MatrixIOException when the payload cannot be processed.
+ /// @throws MatrixNetworkException when the response status is not successful.
List getJoinedRooms();
/// Send an invitation to a user to participate in a room, this endpoint requires the caller to be
@@ -80,7 +94,10 @@ public interface Room {
/// @param request a [JoinRoomRequest] where additional information can be passed.
/// @param via the servers to attempt to join the room through. One of the servers must be
/// participating in the room.
- /// @return the room ID
+ /// @return the room ID.
+ /// @throws MatrixIOException when the payload cannot be processed.
+ /// @throws MatrixNetworkException when the response status is not successful.
+ /// @throws IllegalArgumentException when using an incorrect [Validator].
String joinByRoomIdOrAliasIfAllowed(
Validator roomIdOrAlias, JoinRoomRequest request, List via);
@@ -90,7 +107,9 @@ String joinByRoomIdOrAliasIfAllowed(
/// @param request a [JoinRoomRequest] where additional information can be passed.
/// @param via the servers to attempt to join the room through. One of the servers must be
/// participating in the room.
- /// @return the room ID
+ /// @return the room ID.
+ /// @throws MatrixIOException when the payload cannot be processed.
+ /// @throws MatrixNetworkException when the response status is not successful.
String joinByRoomIdIfAllowed(RoomID roomId, JoinRoomRequest request, List via);
/// Knock on a room to ask for permission to join. Acceptance of this request happens out of band.
@@ -100,6 +119,8 @@ String joinByRoomIdOrAliasIfAllowed(
/// @param via the servers to attempt to join the room through. One of the servers must be
/// participating in the room.
/// @return the room ID of the knocked room.
+ /// @throws MatrixIOException when the payload cannot be processed.
+ /// @throws MatrixNetworkException when the response status is not successful.
String knockOn(Validator roomIdOrAlias, String reason, List via);
/// Sends a request to leave the room, upon success, you will forget all messages from this room.
@@ -171,8 +192,7 @@ String joinByRoomIdOrAliasIfAllowed(
/// @param since a pagination token from a previous request, allowing you to get the next or
/// previous batch of rooms. The direction of pagination is specified by which token is
/// supplied.
- /// @return a [PublicRoomDirectory] containing [io.github.hikingc.matrixsdk.api.rooms.models.PublishedRoomsChunk] records of the published
- /// rooms on the server.
+ /// @return a [PublicRoomDirectory] containing records of the published rooms on the server.
/// @throws MatrixIOException when the payload cannot be processed.
/// @throws NullPointerException when the roomId is null.
/// @see #getPublishedRoomDirectory(PublicRoomRequest)
@@ -182,18 +202,21 @@ String joinByRoomIdOrAliasIfAllowed(
/// Lists a server’s published room directory.
///
/// @param request a [PublicRoomRequest] with additional filters for the request.
- /// @return a [PublicRoomDirectory] containing [io.github.hikingc.matrixsdk.api.rooms.models.PublishedRoomsChunk] records of the published
- /// rooms on the server.
+ /// @return a [PublicRoomDirectory] containing records of the published rooms on the server.
+ /// @throws MatrixIOException when the payload cannot be processed.
+ /// @throws MatrixNetworkException when the response status is not successful.
PublicRoomDirectory getPublishedRoomDirectory(PublicRoomRequest request);
/// Retrieves a summary for a room. The response data might yield outdated, partial or even with
/// no data.
///
- /// @param roomIdOrAlias a [RoomID] or [RoomAlias] of the room to target
+ /// @param roomIdOrAlias a [RoomID] or [RoomAlias] of the room to target.
/// @param via the servers to attempt to request the summary from when the local server cannot
- /// generate it
+ /// generate it.
/// @return a [RoomSummary] containing all the information about the room.
/// @throws MatrixIOException when the payload cannot be processed.
/// @throws NullPointerException when the roomId is null.
+ /// @throws MatrixIOException when the payload cannot be processed.
+ /// @throws MatrixNetworkException when the response status is not successful.
RoomSummary getRoomSummary(Validator roomIdOrAlias, List via);
}
diff --git a/src/main/java/io/github/hikingc/matrixsdk/api/UserData.java b/src/main/java/io/github/hikingc/matrixsdk/api/UserData.java
index 1a0760a..33074e4 100644
--- a/src/main/java/io/github/hikingc/matrixsdk/api/UserData.java
+++ b/src/main/java/io/github/hikingc/matrixsdk/api/UserData.java
@@ -3,12 +3,18 @@
import io.github.hikingc.matrixsdk.api.identifiers.UserID;
import io.github.hikingc.matrixsdk.api.userdata.UserProfile;
import io.github.hikingc.matrixsdk.api.userdata.UsersFound;
+import io.github.hikingc.matrixsdk.exceptions.MatrixIOException;
+import io.github.hikingc.matrixsdk.exceptions.MatrixNetworkException;
/// Core interface for executing protocol operations against User data.
///
/// All operations in this interface are blocking. Implementations must ensure thread safety and
/// avoid synchronization blocks that cause carrier thread pinning during network I/O.
///
+/// Unless otherwise noted, every method in this interface throws [MatrixIOException] if the request
+/// or response payload cannot be processed, and [MatrixNetworkException] if the server's response
+/// status is not successful.
+///
/// @see Matrix Client-Server
/// API Specification for User Data
public interface UserData {
@@ -22,32 +28,42 @@ public interface UserData {
/// @param limit the maximum number of results.
/// @param searchTerm the term to search for.
/// @return all the [UsersFound] by the server.
+ /// @throws MatrixIOException when the payload cannot be processed.
+ /// @throws MatrixNetworkException when the response status is not successful.
UsersFound searchUsersByTerm(Integer limit, String searchTerm);
/// Get the profile of a user
///
- /// @param userId the [UserID] to profile.
- /// @return the corresponding [UserProfile].
+ /// @param userId the [UserID] to target.
+ /// @return its [UserProfile].
+ /// @throws MatrixIOException when the payload cannot be processed.
+ /// @throws MatrixNetworkException when the response status is not successful.
UserProfile getUserProfile(UserID userId);
/// Get the value of a profile field for a user
///
- /// @param userId the [UserID] to profile.
- /// @param keyName a property field
- /// @return the value of the key property.
+ /// @param userId the [UserID] to target.
+ /// @param keyName the key name.
+ /// @return the corresponding value of the pair.
+ /// @throws MatrixIOException when the payload cannot be processed.
+ /// @throws MatrixNetworkException when the response status is not successful.
String getUserProfileByProperty(
UserID userId, String keyName); // only 1 property allowed so no Map
/// Set or update a profile field for a user.
///
- /// @param userId the [UserID] that'll receive the K-V.
- /// @param keyName the key to insert in the profile.
- /// @param valueName the value for the key.
+ /// @param userId the [UserID] to target.
+ /// @param keyName the key name.
+ /// @param valueName the value name.
+ /// @throws MatrixIOException when the payload cannot be processed.
+ /// @throws MatrixNetworkException when the response status is not successful.
void setUserProfileProperty(UserID userId, String keyName, String valueName);
/// Remove a specific field from a user’s profile.
///
- /// @param userId the [UserID] that'll have his K-V deleted.
- /// @param keyName the key to be deleted.
+ /// @param userId the [UserID] that'll have a key-value pair removed from its profile.
+ /// @param keyName the key name.
+ /// @throws MatrixIOException when the payload cannot be processed.
+ /// @throws MatrixNetworkException when the response status is not successful.
void deleteUserProfileProperty(UserID userId, String keyName);
}
diff --git a/src/main/java/io/github/hikingc/matrixsdk/exceptions/MatrixIOException.java b/src/main/java/io/github/hikingc/matrixsdk/exceptions/MatrixIOException.java
index 2571c37..994486b 100644
--- a/src/main/java/io/github/hikingc/matrixsdk/exceptions/MatrixIOException.java
+++ b/src/main/java/io/github/hikingc/matrixsdk/exceptions/MatrixIOException.java
@@ -1,7 +1,7 @@
package io.github.hikingc.matrixsdk.exceptions;
/// Thrown to indicate that the code has attempted to process an I/O event to which it has failed.
-public class MatrixIOException extends RuntimeException {
+public class MatrixIOException extends MatrixException {
/// Constructs a [MatrixIOException] with a message.
///
/// @param message The detail message. The detail message is saved for later retrieval by the
diff --git a/src/main/java/io/github/hikingc/matrixsdk/exceptions/MatrixNetworkException.java b/src/main/java/io/github/hikingc/matrixsdk/exceptions/MatrixNetworkException.java
index 84735c0..2069376 100644
--- a/src/main/java/io/github/hikingc/matrixsdk/exceptions/MatrixNetworkException.java
+++ b/src/main/java/io/github/hikingc/matrixsdk/exceptions/MatrixNetworkException.java
@@ -1,7 +1,7 @@
package io.github.hikingc.matrixsdk.exceptions;
/// Thrown to indicate that the code has not received a successful HTTP status code.
-public class MatrixNetworkException extends RuntimeException {
+public class MatrixNetworkException extends MatrixException {
/// Constructs a [MatrixNetworkException] with a message.
///
/// @param message The detail message. The detail message is saved for later retrieval by the
diff --git a/src/main/java/io/github/hikingc/matrixsdk/services/events/EventService.java b/src/main/java/io/github/hikingc/matrixsdk/services/events/EventService.java
index bd982b6..2d3b39d 100644
--- a/src/main/java/io/github/hikingc/matrixsdk/services/events/EventService.java
+++ b/src/main/java/io/github/hikingc/matrixsdk/services/events/EventService.java
@@ -39,7 +39,7 @@ public EventService(ClientContext context) {
public ClientEvent> getEvent(RoomID roomId, String eventId) {
Objects.requireNonNull(eventId, "The event ID must not be null");
String response =
- httpTransport.getEvent(
+ httpTransport.getRequest(
URI.create(
context.discoveryResponse().homeserver().baseUrl()
+ ROOM_ENDPOINT
@@ -55,7 +55,7 @@ public ClientEvent> getEvent(RoomID roomId, String eventId) {
public RoomMembers getJoinedMembers(RoomID roomId) {
String response =
- httpTransport.getEvent(
+ httpTransport.getRequest(
URI.create(
context.discoveryResponse().homeserver().baseUrl()
+ ROOM_ENDPOINT
@@ -78,7 +78,7 @@ public List getMembers(
ROOM_ENDPOINT + roomId + "/members",
args);
- String response = httpTransport.getEvent(uri, context.token());
+ String response = httpTransport.getRequest(uri, context.token());
// We can skip the chunk parent, we don't use ObjectFromString because it is NOT a raw Array as
// detailed
// on the spec.
@@ -88,7 +88,7 @@ public List getMembers(
@Override
public List> getStateEvents(RoomID roomId) {
String response =
- httpTransport.getEvent(
+ httpTransport.getRequest(
URI.create(
context.discoveryResponse().homeserver().baseUrl()
+ ROOM_ENDPOINT
@@ -109,7 +109,7 @@ public ClientEvent> getStateEvent(RoomID roomId, String eventType, String stat
context.discoveryResponse().homeserver().baseUrl(),
ROOM_ENDPOINT + roomId + "/state/" + eventType + "/" + stateKey,
args);
- String response = httpTransport.getEvent(uri, context.token());
+ String response = httpTransport.getRequest(uri, context.token());
return Mapper.getObjectFromString(response, ClientEvent.class);
}
@@ -128,7 +128,7 @@ public Messages getMessages(
context.discoveryResponse().homeserver().baseUrl(),
ROOM_ENDPOINT + roomId + "/messages",
args);
- String queryResponse = httpTransport.getEvent(uri, context.token());
+ String queryResponse = httpTransport.getRequest(uri, context.token());
return Mapper.getObjectFromString(queryResponse, Messages.class);
}
@@ -145,7 +145,7 @@ public EventMetadata getEventClosestToTimestamp(
var uri =
httpTransport.generateEncodedURI(
context.discoveryResponse().homeserver().baseUrl(), ROOM_ENDPOINT + roomId, args);
- String response = httpTransport.getEvent(uri, context.token());
+ String response = httpTransport.getRequest(uri, context.token());
return Mapper.getObjectFromString(response, EventMetadata.class);
}
@@ -153,7 +153,7 @@ public EventMetadata getEventClosestToTimestamp(
public RoomInfo getInitialSync(RoomID roomId) {
String response =
- httpTransport.getEvent(
+ httpTransport.getRequest(
URI.create(
context.discoveryResponse().homeserver().baseUrl()
+ ROOM_ENDPOINT
@@ -178,7 +178,7 @@ public String sendStateEvent(RoomID roomId, String stateKey, StateEventContent c
context.discoveryResponse().homeserver().baseUrl(),
ROOM_ENDPOINT + roomId + "/state/" + type + "/" + stateKey,
null);
- String response = httpTransport.putEvent(uri, jsonPayload, context.token());
+ String response = httpTransport.putRequest(uri, jsonPayload, context.token());
return Mapper.getStringValueOfAJsonKey(response, "event_id");
}
@@ -198,7 +198,7 @@ public String sendMessageEvent(RoomID roomId, String txnId, MessageEventContent
context.discoveryResponse().homeserver().baseUrl(),
ROOM_ENDPOINT + roomId + "/send/" + type + "/" + txnId,
null);
- String response = httpTransport.putEvent(uri, jsonPayload, context.token());
+ String response = httpTransport.putRequest(uri, jsonPayload, context.token());
return Mapper.getStringValueOfAJsonKey(response, "event_id");
}
@@ -211,7 +211,7 @@ public String redactEvent(RoomID roomId, String eventId, String txnId, @Nullable
json = Mapper.createObjectFromMap(Map.ofEntries(Map.entry("reason", reason)));
}
String response =
- httpTransport.putEvent(
+ httpTransport.putRequest(
URI.create(
context.discoveryResponse().homeserver().baseUrl()
+ ROOM_ENDPOINT
@@ -261,7 +261,7 @@ public Sync sync(QueryParametersSync params) {
httpTransport.generateEncodedURI(
context.discoveryResponse().homeserver().baseUrl(), "/_matrix/client/v3/sync", args);
- String response = httpTransport.getEvent(query, context.token());
+ String response = httpTransport.getRequest(query, context.token());
return Mapper.getObjectFromString(response, Sync.class);
}
@@ -270,7 +270,7 @@ public Sync sync(QueryParametersSync params) {
/// @return a [String] representing the MXC
private String createAndReserveMXC() throws JacksonException {
String queryResponse =
- httpTransport.postEvent(
+ httpTransport.postRequest(
URI.create(
context.discoveryResponse().homeserver().baseUrl()
+ "/_matrix"
diff --git a/src/main/java/io/github/hikingc/matrixsdk/services/filtering/FilterService.java b/src/main/java/io/github/hikingc/matrixsdk/services/filtering/FilterService.java
index d53dac9..b771b6e 100644
--- a/src/main/java/io/github/hikingc/matrixsdk/services/filtering/FilterService.java
+++ b/src/main/java/io/github/hikingc/matrixsdk/services/filtering/FilterService.java
@@ -36,7 +36,7 @@ public String publishFilter(UserID userId, FilterDefinition filter) {
context.discoveryResponse().homeserver().baseUrl(),
USER_FILTER_ENDPOINT + userId + "/filter",
null);
- String responseBody = httpTransport.postEvent(uri, serializedInputData, context.token());
+ String responseBody = httpTransport.postRequest(uri, serializedInputData, context.token());
return Mapper.getStringValueOfAJsonKey(responseBody, "filter_id");
}
@@ -50,6 +50,6 @@ public FilterDefinition getFilter(UserID userId, String filterId) {
USER_FILTER_ENDPOINT + userId + "/filter/" + filterId,
null);
return Mapper.getObjectFromString(
- httpTransport.getEvent(uri, context.token()), FilterDefinition.class);
+ httpTransport.getRequest(uri, context.token()), FilterDefinition.class);
}
}
diff --git a/src/main/java/io/github/hikingc/matrixsdk/services/rooms/RoomService.java b/src/main/java/io/github/hikingc/matrixsdk/services/rooms/RoomService.java
index 60645e7..8f0a899 100644
--- a/src/main/java/io/github/hikingc/matrixsdk/services/rooms/RoomService.java
+++ b/src/main/java/io/github/hikingc/matrixsdk/services/rooms/RoomService.java
@@ -63,7 +63,7 @@ public String create(InitialRoomConfiguration configuration) {
String responseBody;
responseBody =
- httpTransport.postEvent(
+ httpTransport.postRequest(
URI.create(
context.discoveryResponse().homeserver().baseUrl()
+ "/_matrix/client/v3/createRoom"),
@@ -81,7 +81,7 @@ public ResolvedAlias resolveAlias(RoomAlias roomAlias) {
DIRECTORY_ENDPOINT_ROOM + roomAlias,
null);
- var responseBody = httpTransport.getEvent(uri, context.token());
+ var responseBody = httpTransport.getRequest(uri, context.token());
return Mapper.getObjectFromString(responseBody, ResolvedAlias.class);
}
@@ -96,7 +96,7 @@ public void setAlias(RoomAlias roomAlias, RoomID roomId) {
Map map = new HashMap<>();
map.put(ROOM_ID, roomId);
- httpTransport.putEvent(uri, Mapper.createObjectFromMap(map), context.token());
+ httpTransport.putRequest(uri, Mapper.createObjectFromMap(map), context.token());
}
@Override
@@ -106,14 +106,14 @@ public void deleteAlias(RoomAlias roomAlias) {
context.discoveryResponse().homeserver().baseUrl(),
DIRECTORY_ENDPOINT_ROOM + roomAlias,
null);
- httpTransport.deleteEvent(uri, context.token());
+ httpTransport.deleteRequest(uri, context.token());
}
@Override
public List getAliasesOfARoom(RoomID roomId) {
String response =
- httpTransport.getEvent(
+ httpTransport.getRequest(
URI.create(
context.discoveryResponse().homeserver().baseUrl()
+ ROOM_ENDPOINT
@@ -137,7 +137,7 @@ public List getAliasesOfARoom(RoomID roomId) {
@Override
public List getJoinedRooms() {
String response =
- httpTransport.getEvent(
+ httpTransport.getRequest(
URI.create(
context.discoveryResponse().homeserver().baseUrl()
+ "/_matrix"
@@ -155,7 +155,7 @@ public void inviteUser(RoomID roomId, RoomMembershipRequest event) {
} catch (JacksonException e) {
throw new MatrixIOException("Failed to parse input data", e);
}
- httpTransport.postEvent(
+ httpTransport.postRequest(
URI.create(
context.discoveryResponse().homeserver().baseUrl()
+ ROOM_ENDPOINT
@@ -169,7 +169,7 @@ public void inviteUser(RoomID roomId, RoomMembershipRequest event) {
public String joinByRoomIdOrAliasIfAllowed(
Validator roomIdOrAlias, JoinRoomRequest request, List via) {
if (Objects.requireNonNull(roomIdOrAlias) instanceof UserID) {
- throw new MatrixException("Wrong format type");
+ throw new IllegalArgumentException("Wrong format type");
}
Map params = new HashMap<>();
@@ -185,7 +185,7 @@ public String joinByRoomIdOrAliasIfAllowed(
} catch (JacksonException e) {
throw new MatrixIOException("Failed to parse input data", e);
}
- var responseBody = httpTransport.postEvent(uri, serializedInputData, context.token());
+ var responseBody = httpTransport.postRequest(uri, serializedInputData, context.token());
return Mapper.getStringValueOfAJsonKey(responseBody, ROOM_ID);
}
@@ -204,7 +204,7 @@ public String joinByRoomIdIfAllowed(RoomID roomId, JoinRoomRequest request, List
} catch (JacksonException e) {
throw new MatrixIOException("Failed to parse input data", e);
}
- var responseBody = httpTransport.postEvent(uri, serializedInputData, context.token());
+ var responseBody = httpTransport.postRequest(uri, serializedInputData, context.token());
return Mapper.getStringValueOfAJsonKey(responseBody, ROOM_ID);
}
@@ -223,7 +223,7 @@ public String knockOn(Validator roomIdOrAlias, String reason, List via)
map.put("reason", reason);
String responseBody =
- httpTransport.postEvent(uri, Mapper.createObjectFromMap(map), context.token());
+ httpTransport.postRequest(uri, Mapper.createObjectFromMap(map), context.token());
try {
return Mapper.getStringValueOfAJsonKey(responseBody, ROOM_ID);
} catch (JacksonException e) {
@@ -233,7 +233,7 @@ public String knockOn(Validator roomIdOrAlias, String reason, List via)
@Override
public void forget(RoomID roomId) {
- httpTransport.postEvent(
+ httpTransport.postRequest(
URI.create(
context.discoveryResponse().homeserver().baseUrl()
+ ROOM_ENDPOINT
@@ -245,7 +245,7 @@ public void forget(RoomID roomId) {
@Override
public void leave(RoomID roomId) {
- httpTransport.postEvent(
+ httpTransport.postRequest(
URI.create(
context.discoveryResponse().homeserver().baseUrl() + ROOM_ENDPOINT + roomId + "/leave"),
null,
@@ -260,7 +260,7 @@ public void kick(RoomID roomId, RoomMembershipRequest event) {
} catch (JacksonException e) {
throw new MatrixIOException("Failed to parse input data", e);
}
- httpTransport.postEvent(
+ httpTransport.postRequest(
URI.create(
context.discoveryResponse().homeserver().baseUrl() + ROOM_ENDPOINT + roomId + "/kick"),
serializedInputData,
@@ -275,7 +275,7 @@ public void ban(RoomID roomId, RoomMembershipRequest event) {
} catch (JacksonException e) {
throw new MatrixIOException("Failed to parse input data", e);
}
- httpTransport.postEvent(
+ httpTransport.postRequest(
URI.create(
context.discoveryResponse().homeserver().baseUrl() + ROOM_ENDPOINT + roomId + "/ban"),
serializedInputData,
@@ -290,7 +290,7 @@ public void unban(RoomID roomId, RoomMembershipRequest event) {
} catch (JacksonException e) {
throw new MatrixIOException("Failed to parse input data", e);
}
- httpTransport.postEvent(
+ httpTransport.postRequest(
URI.create(
context.discoveryResponse().homeserver().baseUrl() + ROOM_ENDPOINT + roomId + "/unban"),
responseBody,
@@ -300,7 +300,7 @@ public void unban(RoomID roomId, RoomMembershipRequest event) {
@Override
public String getRoomDirectoryVisibilityType(RoomID roomId) {
var responseBody =
- httpTransport.getEvent(
+ httpTransport.getRequest(
URI.create(
context.discoveryResponse().homeserver().baseUrl() + DIRECTORY_ENDPOINT + roomId),
null);
@@ -312,7 +312,7 @@ public void setRoomDirectoryVisibilityType(RoomID roomId, VisibilityRoomType roo
Map map = new HashMap<>();
map.put("visibility", roomType);
- httpTransport.putEvent(
+ httpTransport.putRequest(
URI.create(
context.discoveryResponse().homeserver().baseUrl() + DIRECTORY_ENDPOINT + roomId),
Mapper.createObjectFromMap(map),
@@ -332,7 +332,7 @@ public PublicRoomDirectory getPublishedRoomDirectory(
context.discoveryResponse().homeserver().baseUrl(),
"/_matrix/client/v3/publicRooms",
params);
- var responseBody = httpTransport.getEvent(uri, context.token());
+ var responseBody = httpTransport.getRequest(uri, context.token());
return Mapper.getObjectFromString(responseBody, PublicRoomDirectory.class);
}
@@ -342,7 +342,7 @@ public PublicRoomDirectory getPublishedRoomDirectory(PublicRoomRequest request)
String serializedInputData = objectMapper.writeValueAsString(request);
var responseBody =
- httpTransport.postEvent(
+ httpTransport.postRequest(
URI.create(
context.discoveryResponse().homeserver().baseUrl()
+ "/_matrix/client/v3/publicRooms"),
@@ -365,7 +365,7 @@ public RoomSummary getRoomSummary(Validator roomIdOrAlias, List via) {
context.discoveryResponse().homeserver().baseUrl(),
"/_matrix/client/v1/room_summary/" + roomIdOrAlias,
args);
- var responseBody = httpTransport.getEvent(uri, context.token());
+ var responseBody = httpTransport.getRequest(uri, context.token());
return Mapper.getObjectFromString(responseBody, RoomSummary.class);
}
diff --git a/src/main/java/io/github/hikingc/matrixsdk/services/userdata/UserDataService.java b/src/main/java/io/github/hikingc/matrixsdk/services/userdata/UserDataService.java
index 744b20d..0120359 100644
--- a/src/main/java/io/github/hikingc/matrixsdk/services/userdata/UserDataService.java
+++ b/src/main/java/io/github/hikingc/matrixsdk/services/userdata/UserDataService.java
@@ -44,7 +44,7 @@ public UsersFound searchUsersByTerm(@Nullable Integer limit, String searchTerm)
.formatted(limitToUse, searchTerm);
String responseBody =
- httpTransport.postEvent(
+ httpTransport.postRequest(
URI.create(context.discoveryResponse().homeserver().baseUrl() + USER_DIR),
rawTextPayload,
context.token());
@@ -54,7 +54,7 @@ public UsersFound searchUsersByTerm(@Nullable Integer limit, String searchTerm)
@Override
public UserProfile getUserProfile(UserID userId) {
String responseBody =
- httpTransport.getEvent(
+ httpTransport.getRequest(
URI.create(context.discoveryResponse().homeserver().baseUrl() + PROFILE_DIR + userId),
context.token());
return Mapper.getObjectFromString(responseBody, UserProfile.class);
@@ -64,7 +64,7 @@ public UserProfile getUserProfile(UserID userId) {
public String getUserProfileByProperty(UserID userId, @Nullable String keyName) {
Objects.requireNonNull(keyName, "The key name must no be null");
String responseBody =
- httpTransport.getEvent(
+ httpTransport.getRequest(
URI.create(
context.discoveryResponse().homeserver().baseUrl()
+ PROFILE_DIR
@@ -82,7 +82,7 @@ public void setUserProfileProperty(UserID userId, String keyName, String valueNa
Objects.requireNonNull(valueName, "The value name must no be null");
var serializedJson = Mapper.createObjectFromMap(Map.ofEntries(Map.entry(keyName, valueName)));
- httpTransport.putEvent(
+ httpTransport.putRequest(
URI.create(
context.discoveryResponse().homeserver().baseUrl()
+ PROFILE_DIR
@@ -97,7 +97,7 @@ public void setUserProfileProperty(UserID userId, String keyName, String valueNa
public void deleteUserProfileProperty(UserID userId, String keyName) {
Objects.requireNonNull(keyName, "The key name must no be null");
- httpTransport.deleteEvent(
+ httpTransport.deleteRequest(
URI.create(
context.discoveryResponse().homeserver().baseUrl()
+ PROFILE_DIR
diff --git a/src/main/java/io/github/hikingc/matrixsdk/services/utils/HttpTransport.java b/src/main/java/io/github/hikingc/matrixsdk/services/utils/HttpTransport.java
index 46bf423..3b30155 100644
--- a/src/main/java/io/github/hikingc/matrixsdk/services/utils/HttpTransport.java
+++ b/src/main/java/io/github/hikingc/matrixsdk/services/utils/HttpTransport.java
@@ -19,6 +19,7 @@
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;
+import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
import tools.jackson.core.exc.StreamReadException;
@@ -31,7 +32,7 @@
/// Failed requests are validated against the server's response and throw [MatrixNetworkException],
/// populated with the HTTP status code and any error message returned by the server, and
/// [MatrixIOException] if the server JSON response wasn't even sent.
-@Nullable
+@NullMarked
public class HttpTransport {
private static final String CONTENT_TYPE = "Content-Type";
private static final String APPLICATION_JSON = "application/json";
@@ -46,6 +47,12 @@ public HttpTransport(int timeOut) {
client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(timeOut)).build();
}
+ /// Handles return code validation from Matrix servers.
+ ///
+ /// @param code an HTTP Code.
+ /// @param body the response body from the server.
+ /// @throws MatrixIOException if an I/O error has occurred while parsing the response.
+ /// @throws MatrixNetworkException when the server responds with an unsuccessful HTTP Code.
private void validateResponse(int code, String body) {
if (code >= 200 && code < 300) {
return;
@@ -74,8 +81,10 @@ private void validateResponse(int code, String body) {
/// @param path the [URI] of the endpoint to `GET`.
/// @param authToken if supplied, the `Bearer` token.
/// @return a JSON [String].
- /// @throws IllegalArgumentException if the path was not supplied
- public String getEvent(URI path, String authToken) {
+ /// @throws MatrixIOException if an I/O error has occurred while sending the request.
+ /// @throws MatrixNetworkException if the operation has been interrupted.
+ /// @throws IllegalArgumentException if the path was not supplied.
+ public String getRequest(URI path, @Nullable String authToken) {
var builderRequest =
HttpRequest.newBuilder().uri(path).header(CONTENT_TYPE, APPLICATION_JSON).GET();
@@ -104,9 +113,10 @@ public String getEvent(URI path, String authToken) {
/// @param body a JSON [String].
/// @param authToken if supplied, the `Bearer` token.
/// @return a JSON [String].
- /// @throws MatrixIOException if an I/O error has occurred while sending the request
- /// @throws MatrixNetworkException if the path was not supplied
- public String postEvent(URI path, String body, String authToken) {
+ /// @throws MatrixIOException if an I/O error has occurred while sending the request.
+ /// @throws MatrixNetworkException if the operation has been interrupted.
+ /// @throws IllegalArgumentException if the path was not supplied.
+ public String postRequest(URI path, @Nullable String body, @Nullable String authToken) {
var builderRequest = HttpRequest.newBuilder().uri(path);
if (body != null) {
@@ -139,12 +149,15 @@ public String postEvent(URI path, String body, String authToken) {
/// Sends a `POST` request to the given endpoint.
///
+ /// This endpoint is exclusively used for Authentication workflows with OAuth 2.0.
+ ///
/// @param path the [URI] of the endpoint to query.
/// @param body a JSON [String].
/// @return a JSON [String].
- /// @throws MatrixIOException if an I/O error has occurred while sending the request
- /// @throws MatrixNetworkException if the path was not supplied
- public String postEventAuth(URI path, String body) {
+ /// @throws MatrixIOException if an I/O error has occurred while sending the request.
+ /// @throws MatrixNetworkException if the operation has been interrupted.
+ /// @throws IllegalArgumentException if the path was not supplied.
+ public String postAuth(URI path, @Nullable String body) {
var builderRequest = HttpRequest.newBuilder().uri(path);
builderRequest.header(CONTENT_TYPE, "application/x-www-form-urlencoded");
@@ -176,10 +189,10 @@ public String postEventAuth(URI path, String body) {
/// @param body a JSON [String]
/// @param authToken if supplied, the `Bearer` token.
/// @return a JSON [String] when the operation is successful.
- /// @throws MatrixIOException if an I/O error has occurred while sending the request
- /// @throws MatrixNetworkException if the operation has been interrupted
- /// @throws IllegalArgumentException if the path was not supplied
- public String putEvent(URI path, String body, String authToken) {
+ /// @throws MatrixIOException if an I/O error has occurred while sending the request.
+ /// @throws MatrixNetworkException if the operation has been interrupted.
+ /// @throws IllegalArgumentException if the path was not supplied.
+ public String putRequest(URI path, @Nullable String body, String authToken) {
var builderRequest =
HttpRequest.newBuilder()
@@ -206,7 +219,9 @@ public String putEvent(URI path, String body, String authToken) {
return response.body();
}
- /// Sends a `PUT` request to the given endpoint.
+ /// Sends a `PUT` request to the given endpoint to upload a resource.
+ ///
+ /// The [#CONTENT_TYPE] will be generated using [Files#probeContentType(Path)]
///
/// @param path the [URI] of the endpoint to query.
/// @param resource a [Path] pointing to the resource to be uploaded.
@@ -249,10 +264,10 @@ public String putResource(URI path, Path resource, String authToken) {
/// @param path the [URI] of the endpoint to query.
/// @param authToken if supplied, the `Bearer` token.
/// @return a JSON [String].
- /// @throws MatrixIOException if an I/O error has occurred while sending the request
- /// @throws MatrixNetworkException if the operation has been interrupted
- /// @throws IllegalArgumentException if the path was not supplied
- public String deleteEvent(URI path, String authToken) {
+ /// @throws MatrixIOException if an I/O error has occurred while sending the request.
+ /// @throws MatrixNetworkException if the operation has been interrupted.
+ /// @throws IllegalArgumentException if the path was not supplied.
+ public String deleteRequest(URI path, String authToken) {
HttpRequest deleteRequest =
HttpRequest.newBuilder()
.uri(path)
@@ -276,8 +291,8 @@ public String deleteEvent(URI path, String authToken) {
/// URL-encodes a string using UTF-8.
///
- /// @param value the string to encode
- /// @return the URL-encoded string
+ /// @param value the string to encode.
+ /// @return the URL-encoded string.
private String encode(String value) {
return URLEncoder.encode(value, StandardCharsets.UTF_8);
}
@@ -289,8 +304,8 @@ private String encode(String value) {
/// @param path the path, for example: `/_matrix/client/v3/join/!room:example.org`
/// @param params query parameters; accepts wrapped primitives and Lists for repeated parameters.
/// Null values, null list items, or a null/empty map are all safely ignored.
- /// @return a safe, fully composed [URI]
- public URI generateEncodedURI(String baseUrl, String path, Map params) {
+ /// @return a safe, fully composed [URI].
+ public URI generateEncodedURI(String baseUrl, String path, @Nullable Map params) {
String query = encodeQueryParams(params);
try {
URI base = URI.create(baseUrl);
@@ -308,7 +323,7 @@ public URI generateEncodedURI(String baseUrl, String path, Map p
/// @param path the path, for example: `/_matrix/client/v3/join/!room:example.org`
/// @param params query parameters; accepts wrapped primitives and Lists for repeated parameters.
/// Null values, null list items, or a null/empty map are all safely ignored.
- /// @return a safe, fully composed [URI]
+ /// @return a safe, fully composed [URI].
public URI generateRawURI(String baseUrl, String path, Map params) {
String query = rawQueryParams(params);
try {
@@ -320,7 +335,7 @@ public URI generateRawURI(String baseUrl, String path, Map param
}
}
- private String encodeQueryParams(Map params) {
+ private String encodeQueryParams(@Nullable Map params) {
if (params == null || params.isEmpty()) return "";
return params.entrySet().stream()
.filter(e -> e.getValue() != null)
@@ -329,7 +344,7 @@ private String encodeQueryParams(Map params) {
.collect(Collectors.joining("&"));
}
- private String rawQueryParams(Map params) {
+ private String rawQueryParams(@Nullable Map params) {
if (params == null || params.isEmpty()) return "";
return params.entrySet().stream()
.filter(e -> e.getValue() != null)
diff --git a/src/main/java/io/github/hikingc/matrixsdk/services/utils/Mapper.java b/src/main/java/io/github/hikingc/matrixsdk/services/utils/Mapper.java
index c28b2e7..ca09421 100644
--- a/src/main/java/io/github/hikingc/matrixsdk/services/utils/Mapper.java
+++ b/src/main/java/io/github/hikingc/matrixsdk/services/utils/Mapper.java
@@ -40,6 +40,7 @@ private static ObjectMapper buildMapper() {
/// @param json a JSON [String].
/// @param key the key of the JSON Object.
/// @return the corresponding value.
+ /// @throws MatrixIOException when the key was not in the response
public static String getStringValueOfAJsonKey(String json, String key) {
JsonNode tree = INSTANCE.readTree(json);
if (tree == null || tree.isMissingNode()) {
@@ -57,6 +58,7 @@ public static String getStringValueOfAJsonKey(String json, String key) {
/// @param elementType the [Class] to deserialize each element into.
/// @param the type to deserialize each element into
/// @return the deserialized [List] of values for the given key
+ /// @throws MatrixIOException when the key was not in the response or the key value was not an Array
public static List getListFromAJsonKey(String json, String key, Class elementType) {
JsonNode tree = INSTANCE.readTree(json);
JsonNode value = tree.get(key);
@@ -107,7 +109,7 @@ public static String createObjectFromMap(@Nullable Map
/// @param type the target class to deserialize into
/// @param the [Class] type to deserialize into
/// @return the deserialized [Object]
- /// @throws MatrixIOException if the JSON cannot be parsed into the target type
+ /// @throws MatrixIOException if the response cannot be parsed into the target type.
public static T getObjectFromString(@Nullable String responseBody, @Nullable Class type) {
if (responseBody == null || type == null) {
throw new IllegalArgumentException("responseBody and type must not be null");
@@ -128,7 +130,7 @@ public static T getObjectFromString(@Nullable String responseBody, @Nullable
/// @param type a [TypeReference]
/// @param the [Class] type to deserialize into
/// @return the deserialized [Object]
- /// @throws MatrixIOException if the JSON cannot be parsed into the target type
+ /// @throws MatrixIOException if the response cannot be parsed into the target type
public static T getObjectFromString(
@Nullable String responseBody, @Nullable TypeReference type) {
if (responseBody == null || type == null) {