Merge the matrix-java-sdk due to it no longer maintained. Remove thirdparty repositories.
This commit is contained in:
409
src/main/java/io/kamax/matrix/client/AMatrixHttpClient.java
Normal file
409
src/main/java/io/kamax/matrix/client/AMatrixHttpClient.java
Normal file
@@ -0,0 +1,409 @@
|
||||
/*
|
||||
* matrix-java-sdk - Matrix Client SDK for Java
|
||||
* Copyright (C) 2017 Kamax Sarl
|
||||
*
|
||||
* https://www.kamax.io/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.kamax.matrix.client;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
|
||||
import io.kamax.matrix.MatrixErrorInfo;
|
||||
import io.kamax.matrix._MatrixID;
|
||||
import io.kamax.matrix.hs._MatrixHomeserver;
|
||||
import io.kamax.matrix.json.GsonUtil;
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
|
||||
import okhttp3.*;
|
||||
|
||||
public abstract class AMatrixHttpClient implements _MatrixClientRaw {
|
||||
|
||||
private Logger log = LoggerFactory.getLogger(AMatrixHttpClient.class);
|
||||
|
||||
protected MatrixClientContext context;
|
||||
|
||||
protected Gson gson = GsonUtil.get();
|
||||
protected JsonParser jsonParser = new JsonParser();
|
||||
private OkHttpClient client;
|
||||
|
||||
public AMatrixHttpClient(String domain) {
|
||||
this(new MatrixClientContext().setDomain(domain));
|
||||
}
|
||||
|
||||
public AMatrixHttpClient(URL hsBaseUrl) {
|
||||
this(new MatrixClientContext().setHsBaseUrl(hsBaseUrl));
|
||||
}
|
||||
|
||||
protected AMatrixHttpClient(MatrixClientContext context) {
|
||||
this(context, new OkHttpClient.Builder(), new MatrixClientDefaults());
|
||||
}
|
||||
|
||||
protected AMatrixHttpClient(MatrixClientContext context, OkHttpClient.Builder client) {
|
||||
this(context, client, new MatrixClientDefaults());
|
||||
}
|
||||
|
||||
protected AMatrixHttpClient(MatrixClientContext context, OkHttpClient.Builder client,
|
||||
MatrixClientDefaults defaults) {
|
||||
this(context, client.connectTimeout(defaults.getConnectTimeout(), TimeUnit.MILLISECONDS)
|
||||
.readTimeout(5, TimeUnit.MINUTES).followRedirects(false).build());
|
||||
}
|
||||
|
||||
protected AMatrixHttpClient(MatrixClientContext context, OkHttpClient client) {
|
||||
this.context = context;
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<_AutoDiscoverySettings> discoverSettings() {
|
||||
if (StringUtils.isBlank(context.getDomain())) {
|
||||
throw new IllegalStateException("A non-empty Matrix domain must be set to discover the client settings");
|
||||
}
|
||||
|
||||
String hostname = context.getDomain().split(":")[0];
|
||||
log.info("Performing .well-known auto-discovery for {}", hostname);
|
||||
|
||||
URL url = new HttpUrl.Builder().scheme("https").host(hostname).addPathSegments(".well-known/matrix/client")
|
||||
.build().url();
|
||||
String body = execute(new MatrixHttpRequest(new Request.Builder().get().url(url)).addIgnoredErrorCode(404));
|
||||
if (StringUtils.isBlank(body)) {
|
||||
if (Objects.isNull(context.getHsBaseUrl())) {
|
||||
throw new IllegalStateException("No valid Homeserver base URL was found");
|
||||
}
|
||||
|
||||
// No .well-known data found
|
||||
// FIXME improve SDK so we can differentiate between not found and empty.
|
||||
// not found = skip
|
||||
// empty = failure
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
log.info("Found body: {}", body);
|
||||
|
||||
WellKnownAutoDiscoverySettings settings = new WellKnownAutoDiscoverySettings(body);
|
||||
log.info("Found .well-known data");
|
||||
|
||||
// TODO reconsider if and where we should check for an already present HS url in the context
|
||||
if (settings.getHsBaseUrls().isEmpty()) {
|
||||
throw new IllegalStateException("No valid Homeserver base URL was found");
|
||||
}
|
||||
|
||||
for (URL baseUrlCandidate : settings.getHsBaseUrls()) {
|
||||
context.setHsBaseUrl(baseUrlCandidate);
|
||||
try {
|
||||
if (!getHomeApiVersions().isEmpty()) {
|
||||
log.info("Found a valid HS at {}", getContext().getHsBaseUrl().toString());
|
||||
break;
|
||||
}
|
||||
} catch (MatrixClientRequestException e) {
|
||||
log.warn("Error when trying to fetch {}: {}", baseUrlCandidate, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
for (URL baseUrlCandidate : settings.getIsBaseUrls()) {
|
||||
context.setIsBaseUrl(baseUrlCandidate);
|
||||
try {
|
||||
if (validateIsBaseUrl()) {
|
||||
log.info("Found a valid IS at {}", getContext().getIsBaseUrl().toString());
|
||||
break;
|
||||
}
|
||||
} catch (MatrixClientRequestException e) {
|
||||
log.warn("Error when trying to fetch {}: {}", baseUrlCandidate, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
return Optional.of(settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MatrixClientContext getContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public _MatrixHomeserver getHomeserver() {
|
||||
return context.getHomeserver();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> getAccessToken() {
|
||||
return Optional.ofNullable(context.getToken());
|
||||
}
|
||||
|
||||
public String getAccessTokenOrThrow() {
|
||||
return getAccessToken()
|
||||
.orElseThrow(() -> new IllegalStateException("This method can only be used with a valid token."));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getHomeApiVersions() {
|
||||
String body = execute(new Request.Builder().get().url(getPath("client", "", "versions")));
|
||||
return GsonUtil.asList(GsonUtil.parseObj(body), "versions", String.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validateIsBaseUrl() {
|
||||
String body = execute(new Request.Builder().get().url(getIdentityPath("identity", "api", "v1")));
|
||||
return "{}".equals(body);
|
||||
}
|
||||
|
||||
protected String getUserId() {
|
||||
return getUser().orElseThrow(IllegalStateException::new).getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<_MatrixID> getUser() {
|
||||
return context.getUser();
|
||||
}
|
||||
|
||||
protected Request.Builder addAuthHeader(Request.Builder builder, String token) {
|
||||
builder.addHeader("Authorization", "Bearer " + token);
|
||||
return builder;
|
||||
}
|
||||
|
||||
protected Request.Builder addAuthHeader(Request.Builder builder) {
|
||||
return addAuthHeader(builder, getAccessTokenOrThrow());
|
||||
}
|
||||
|
||||
protected String executeAuthenticated(Request.Builder builder, String token) {
|
||||
return execute(addAuthHeader(builder, token));
|
||||
}
|
||||
|
||||
protected String executeAuthenticated(Request.Builder builder) {
|
||||
return execute(addAuthHeader(builder));
|
||||
}
|
||||
|
||||
protected String executeAuthenticated(MatrixHttpRequest matrixRequest) {
|
||||
addAuthHeader(matrixRequest.getHttpRequest());
|
||||
return execute(matrixRequest);
|
||||
}
|
||||
|
||||
protected String execute(Request.Builder builder) {
|
||||
return execute(new MatrixHttpRequest(builder));
|
||||
}
|
||||
|
||||
protected String execute(MatrixHttpRequest matrixRequest) {
|
||||
log(matrixRequest.getHttpRequest());
|
||||
try (Response response = client.newCall(matrixRequest.getHttpRequest().build()).execute()) {
|
||||
String body = response.body().string();
|
||||
int responseStatus = response.code();
|
||||
|
||||
if (responseStatus == 200) {
|
||||
log.debug("Request successfully executed.");
|
||||
} else if (matrixRequest.getIgnoredErrorCodes().contains(responseStatus)) {
|
||||
log.debug("Error code ignored: " + responseStatus);
|
||||
return "";
|
||||
} else {
|
||||
MatrixErrorInfo info = createErrorInfo(body, responseStatus);
|
||||
|
||||
body = handleError(matrixRequest, responseStatus, info);
|
||||
}
|
||||
return body;
|
||||
} catch (IOException e) {
|
||||
throw new MatrixClientRequestException(e);
|
||||
}
|
||||
}
|
||||
|
||||
protected MatrixHttpContentResult executeContentRequest(MatrixHttpRequest matrixRequest) {
|
||||
log(matrixRequest.getHttpRequest());
|
||||
try (Response response = client.newCall(matrixRequest.getHttpRequest().build()).execute()) {
|
||||
int responseStatus = response.code();
|
||||
|
||||
MatrixHttpContentResult result;
|
||||
|
||||
if (responseStatus == 200 || matrixRequest.getIgnoredErrorCodes().contains(responseStatus)) {
|
||||
log.debug("Request successfully executed.");
|
||||
result = new MatrixHttpContentResult(response);
|
||||
} else {
|
||||
String body = response.body().string();
|
||||
MatrixErrorInfo info = createErrorInfo(body, responseStatus);
|
||||
|
||||
result = handleErrorContentRequest(matrixRequest, responseStatus, info);
|
||||
}
|
||||
return result;
|
||||
} catch (IOException e) {
|
||||
throw new MatrixClientRequestException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Default handling of errors. Can be overwritten by a custom implementation in inherited classes.
|
||||
*
|
||||
* @param matrixRequest
|
||||
* @param responseStatus
|
||||
* @param info
|
||||
* @return body of the response of a repeated call of the request, else this methods throws a
|
||||
* MatrixClientRequestException
|
||||
*/
|
||||
protected String handleError(MatrixHttpRequest matrixRequest, int responseStatus, MatrixErrorInfo info) {
|
||||
String message = String.format("Request failed: %s", responseStatus);
|
||||
|
||||
if (Objects.nonNull(info)) {
|
||||
message = String.format("%s - %s - %s", message, info.getErrcode(), info.getError());
|
||||
}
|
||||
|
||||
if (responseStatus == 429) {
|
||||
return handleRateLimited(matrixRequest, info);
|
||||
}
|
||||
|
||||
throw new MatrixClientRequestException(info, message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Default handling of rate limited calls. Can be overwritten by a custom implementation in inherited classes.
|
||||
*
|
||||
* @param matrixRequest
|
||||
* @param info
|
||||
* @return body of the response of a repeated call of the request, else this methods throws a
|
||||
* MatrixClientRequestException
|
||||
*/
|
||||
protected String handleRateLimited(MatrixHttpRequest matrixRequest, MatrixErrorInfo info) {
|
||||
throw new MatrixClientRequestException(info, "Request was rate limited.");
|
||||
// TODO Add default handling of rate limited call, i.e. repeated call after given time interval.
|
||||
// 1. Wait for timeout
|
||||
// 2. return execute(request)
|
||||
}
|
||||
|
||||
protected MatrixHttpContentResult handleErrorContentRequest(MatrixHttpRequest matrixRequest, int responseStatus,
|
||||
MatrixErrorInfo info) {
|
||||
String message = String.format("Request failed with status code: %s", responseStatus);
|
||||
|
||||
if (responseStatus == 429) {
|
||||
return handleRateLimitedContentRequest(matrixRequest, info);
|
||||
}
|
||||
|
||||
throw new MatrixClientRequestException(info, message);
|
||||
}
|
||||
|
||||
protected MatrixHttpContentResult handleRateLimitedContentRequest(MatrixHttpRequest matrixRequest,
|
||||
MatrixErrorInfo info) {
|
||||
throw new MatrixClientRequestRateLimitedException(info, "Request was rate limited.");
|
||||
// TODO Add default handling of rate limited call, i.e. repeated call after given time interval.
|
||||
// 1. Wait for timeout
|
||||
// 2. return execute(request)
|
||||
}
|
||||
|
||||
protected Optional<String> extractAsStringFromBody(String body, String jsonObjectName) {
|
||||
if (StringUtils.isEmpty(body)) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
return GsonUtil.findString(jsonParser.parse(body).getAsJsonObject(), jsonObjectName);
|
||||
}
|
||||
|
||||
private MatrixErrorInfo createErrorInfo(String body, int responseStatus) {
|
||||
MatrixErrorInfo info = null;
|
||||
|
||||
try {
|
||||
info = gson.fromJson(body, MatrixErrorInfo.class);
|
||||
if (Objects.nonNull(info)) {
|
||||
log.debug("Request returned with an error. Status code: {}, errcode: {}, error: {}", responseStatus,
|
||||
info.getErrcode(), info.getError());
|
||||
}
|
||||
} catch (JsonSyntaxException e) {
|
||||
log.debug("Unable to parse Matrix error info. Content was:\n{}", body);
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
private void log(Request.Builder req) {
|
||||
log.debug("Doing {} {}", req, req.toString());
|
||||
}
|
||||
|
||||
protected HttpUrl.Builder getHsBaseUrl() {
|
||||
return HttpUrl.get(context.getHsBaseUrl()).newBuilder();
|
||||
}
|
||||
|
||||
protected HttpUrl.Builder getIsBaseUrl() {
|
||||
return HttpUrl.get(context.getIsBaseUrl()).newBuilder();
|
||||
}
|
||||
|
||||
protected HttpUrl.Builder getPathBuilder(HttpUrl.Builder base, String... segments) {
|
||||
base.addPathSegment("_matrix");
|
||||
for (String segment : segments) {
|
||||
base.addPathSegment(segment);
|
||||
}
|
||||
|
||||
if (context.isVirtual()) {
|
||||
context.getUser().ifPresent(user -> base.addQueryParameter("user_id", user.getId()));
|
||||
}
|
||||
return base;
|
||||
}
|
||||
|
||||
protected HttpUrl.Builder getPathBuilder(String... segments) {
|
||||
return getPathBuilder(getHsBaseUrl(), segments);
|
||||
}
|
||||
|
||||
protected HttpUrl.Builder getIdentityPathBuilder(String... segments) {
|
||||
return getPathBuilder(getIsBaseUrl(), segments);
|
||||
}
|
||||
|
||||
protected URL getPath(String... segments) {
|
||||
return getPathBuilder(segments).build().url();
|
||||
}
|
||||
|
||||
protected URL getIdentityPath(String... segments) {
|
||||
return getIdentityPathBuilder(segments).build().url();
|
||||
}
|
||||
|
||||
protected HttpUrl.Builder getClientPathBuilder(String... segments) {
|
||||
String[] base = { "client", "r0" };
|
||||
segments = ArrayUtils.addAll(base, segments);
|
||||
return getPathBuilder(segments);
|
||||
}
|
||||
|
||||
protected HttpUrl.Builder getMediaPathBuilder(String... segments) {
|
||||
String[] base = { "media", "r0" };
|
||||
segments = ArrayUtils.addAll(base, segments);
|
||||
return getPathBuilder(segments);
|
||||
}
|
||||
|
||||
protected URL getClientPath(String... segments) {
|
||||
return getClientPathBuilder(segments).build().url();
|
||||
}
|
||||
|
||||
protected URL getMediaPath(String... segments) {
|
||||
return getMediaPathBuilder(segments).build().url();
|
||||
}
|
||||
|
||||
protected RequestBody getJsonBody(Object o) {
|
||||
return RequestBody.create(MediaType.parse("application/json"), GsonUtil.get().toJson(o));
|
||||
}
|
||||
|
||||
protected Request.Builder request(URL url) {
|
||||
return new Request.Builder().url(url);
|
||||
}
|
||||
|
||||
protected Request.Builder getRequest(URL url) {
|
||||
return request(url).get();
|
||||
}
|
||||
|
||||
}
|
154
src/main/java/io/kamax/matrix/client/MatrixClientContext.java
Normal file
154
src/main/java/io/kamax/matrix/client/MatrixClientContext.java
Normal file
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* matrix-java-sdk - Matrix Client SDK for Java
|
||||
* Copyright (C) 2017 Kamax Sarl
|
||||
*
|
||||
* https://www.kamax.io/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.kamax.matrix.client;
|
||||
|
||||
import io.kamax.matrix.MatrixID;
|
||||
import io.kamax.matrix._MatrixID;
|
||||
import io.kamax.matrix.hs.MatrixHomeserver;
|
||||
import io.kamax.matrix.hs._MatrixHomeserver;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
public class MatrixClientContext {
|
||||
|
||||
private String domain;
|
||||
private URL hsBaseUrl;
|
||||
private URL isBaseUrl;
|
||||
private _MatrixID user;
|
||||
private String token;
|
||||
private boolean isVirtual;
|
||||
private String deviceId;
|
||||
private String initialDeviceName;
|
||||
|
||||
public MatrixClientContext() {
|
||||
// stub
|
||||
}
|
||||
|
||||
public MatrixClientContext(MatrixClientContext other) {
|
||||
this.domain = other.domain;
|
||||
this.hsBaseUrl = other.hsBaseUrl;
|
||||
this.isBaseUrl = other.isBaseUrl;
|
||||
this.user = other.user;
|
||||
this.token = other.token;
|
||||
this.isVirtual = other.isVirtual;
|
||||
this.deviceId = other.deviceId;
|
||||
this.initialDeviceName = other.initialDeviceName;
|
||||
}
|
||||
|
||||
public MatrixClientContext(_MatrixHomeserver hs) {
|
||||
setDomain(hs.getDomain());
|
||||
setHsBaseUrl(hs.getBaseEndpoint());
|
||||
}
|
||||
|
||||
public MatrixClientContext(_MatrixHomeserver hs, _MatrixID user, String token) {
|
||||
this(hs);
|
||||
setUser(user);
|
||||
setToken(token);
|
||||
}
|
||||
|
||||
public _MatrixHomeserver getHomeserver() {
|
||||
if (Objects.isNull(hsBaseUrl)) {
|
||||
throw new IllegalStateException("Homeserver Base URL is not set");
|
||||
}
|
||||
|
||||
return new MatrixHomeserver(domain, hsBaseUrl.toString());
|
||||
}
|
||||
|
||||
public String getDomain() {
|
||||
return domain;
|
||||
}
|
||||
|
||||
public MatrixClientContext setDomain(String domain) {
|
||||
this.domain = domain;
|
||||
return this;
|
||||
}
|
||||
|
||||
public URL getHsBaseUrl() {
|
||||
return hsBaseUrl;
|
||||
}
|
||||
|
||||
public MatrixClientContext setHsBaseUrl(URL hsBaseUrl) {
|
||||
this.hsBaseUrl = hsBaseUrl;
|
||||
return this;
|
||||
}
|
||||
|
||||
public URL getIsBaseUrl() {
|
||||
return isBaseUrl;
|
||||
}
|
||||
|
||||
public MatrixClientContext setIsBaseUrl(URL isBaseUrl) {
|
||||
this.isBaseUrl = isBaseUrl;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Optional<_MatrixID> getUser() {
|
||||
return Optional.ofNullable(user);
|
||||
}
|
||||
|
||||
public MatrixClientContext setUser(_MatrixID user) {
|
||||
this.user = user;
|
||||
return this;
|
||||
}
|
||||
|
||||
public MatrixClientContext setUserWithLocalpart(String localpart) {
|
||||
setUser(MatrixID.asAcceptable(localpart, getDomain()));
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getToken() {
|
||||
return token;
|
||||
}
|
||||
|
||||
public MatrixClientContext setToken(String token) {
|
||||
this.token = token;
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isVirtual() {
|
||||
return isVirtual;
|
||||
}
|
||||
|
||||
public MatrixClientContext setVirtual(boolean virtual) {
|
||||
isVirtual = virtual;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getDeviceId() {
|
||||
return deviceId;
|
||||
}
|
||||
|
||||
public MatrixClientContext setDeviceId(String deviceId) {
|
||||
this.deviceId = deviceId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getInitialDeviceName() {
|
||||
return initialDeviceName;
|
||||
}
|
||||
|
||||
public MatrixClientContext setInitialDeviceName(String initialDeviceName) {
|
||||
this.initialDeviceName = initialDeviceName;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* matrix-java-sdk - Matrix Client SDK for Java
|
||||
* Copyright (C) 2018 Kamax Sarl
|
||||
*
|
||||
* https://www.kamax.io/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.kamax.matrix.client;
|
||||
|
||||
public class MatrixClientDefaults {
|
||||
|
||||
private int connectTimeout = 30 * 1000; // 30 sec
|
||||
private int requestTimeout = 5 * 60 * 1000; // 5 min
|
||||
private int socketTimeout = requestTimeout;
|
||||
|
||||
public int getConnectTimeout() {
|
||||
return connectTimeout;
|
||||
}
|
||||
|
||||
public MatrixClientDefaults setConnectTimeout(int connectTimeout) {
|
||||
this.connectTimeout = connectTimeout;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public int getRequestTimeout() {
|
||||
return requestTimeout;
|
||||
}
|
||||
|
||||
public MatrixClientDefaults setRequestTimeout(int requestTimeout) {
|
||||
this.requestTimeout = requestTimeout;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public int getSocketTimeout() {
|
||||
return socketTimeout;
|
||||
}
|
||||
|
||||
public MatrixClientDefaults setSocketTimeout(int socketTimeout) {
|
||||
this.socketTimeout = socketTimeout;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* matrix-java-sdk - Matrix Client SDK for Java
|
||||
* Copyright (C) 2017 Kamax Sarl
|
||||
*
|
||||
* https://www.kamax.io/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.kamax.matrix.client;
|
||||
|
||||
import io.kamax.matrix.MatrixErrorInfo;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Optional;
|
||||
|
||||
public class MatrixClientRequestException extends RuntimeException {
|
||||
|
||||
private MatrixErrorInfo errorInfo;
|
||||
|
||||
public MatrixClientRequestException(IOException e) {
|
||||
super(e);
|
||||
}
|
||||
|
||||
public MatrixClientRequestException(MatrixErrorInfo errorInfo, String message) {
|
||||
super(message);
|
||||
|
||||
this.errorInfo = errorInfo;
|
||||
}
|
||||
|
||||
public Optional<MatrixErrorInfo> getError() {
|
||||
return Optional.ofNullable(errorInfo);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* matrix-java-sdk - Matrix Client SDK for Java
|
||||
* Copyright (C) 2018 Kamax Sarl
|
||||
*
|
||||
* https://www.kamax.io/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.kamax.matrix.client;
|
||||
|
||||
import io.kamax.matrix.MatrixErrorInfo;
|
||||
|
||||
public class MatrixClientRequestRateLimitedException extends MatrixClientRequestException {
|
||||
|
||||
public MatrixClientRequestRateLimitedException(MatrixErrorInfo errorInfo, String message) {
|
||||
super(errorInfo, message);
|
||||
}
|
||||
|
||||
}
|
133
src/main/java/io/kamax/matrix/client/MatrixHttpContent.java
Normal file
133
src/main/java/io/kamax/matrix/client/MatrixHttpContent.java
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* matrix-java-sdk - Matrix Client SDK for Java
|
||||
* Copyright (C) 2017 Kamax Sarl
|
||||
*
|
||||
* https://www.kamax.io/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.kamax.matrix.client;
|
||||
|
||||
import io.kamax.matrix._MatrixContent;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.Optional;
|
||||
|
||||
|
||||
import okhttp3.Request;
|
||||
|
||||
public class MatrixHttpContent extends AMatrixHttpClient implements _MatrixContent {
|
||||
|
||||
private Logger log = LoggerFactory.getLogger(MatrixHttpContent.class);
|
||||
private final Pattern filenamePattern = Pattern.compile("filename=\"?([^\";]+)");
|
||||
private URI address;
|
||||
|
||||
private MatrixHttpContentResult result;
|
||||
|
||||
private boolean loaded = false;
|
||||
private boolean valid = false;
|
||||
|
||||
public MatrixHttpContent(MatrixClientContext context, URI address) {
|
||||
super(context);
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
// TODO switch a HTTP HEAD to fetch initial data, instead of loading in memory directly
|
||||
private synchronized void load() {
|
||||
if (loaded) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (!StringUtils.equalsIgnoreCase("mxc", address.getScheme())) {
|
||||
log.debug("{} is not a supported protocol for avatars, ignoring", address.getScheme());
|
||||
} else {
|
||||
MatrixHttpRequest request = new MatrixHttpRequest(new Request.Builder().url(getPermaLink()));
|
||||
result = executeContentRequest(request);
|
||||
valid = result.isValid();
|
||||
}
|
||||
|
||||
} catch (MatrixClientRequestException e) {
|
||||
valid = false;
|
||||
}
|
||||
loaded = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getPermaLink() {
|
||||
return getMediaPathBuilder("download", address.getHost()).addEncodedPathSegments(address.getPath().substring(1))
|
||||
.build().url();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
load();
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> getType() {
|
||||
load();
|
||||
|
||||
if (!isValid()) {
|
||||
throw new IllegalStateException("This method should only be called, if valid is true.");
|
||||
}
|
||||
return result.getContentType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getData() {
|
||||
load();
|
||||
|
||||
if (!isValid()) {
|
||||
throw new IllegalStateException("This method should only be called, if valid is true.");
|
||||
}
|
||||
return result.getData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> getFilename() {
|
||||
load();
|
||||
|
||||
if (!isValid()) {
|
||||
throw new IllegalStateException("This method should only be called, if valid is true.");
|
||||
}
|
||||
|
||||
return result.getHeader("Content-Disposition").filter(l -> !l.isEmpty()).flatMap(l -> {
|
||||
for (String v : l) {
|
||||
Matcher m = filenamePattern.matcher(v);
|
||||
if (m.find()) {
|
||||
return Optional.of(m.group(1));
|
||||
}
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* matrix-java-sdk - Matrix Client SDK for Java
|
||||
* Copyright (C) 2017 Kamax Sarl
|
||||
*
|
||||
* https://www.kamax.io/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.kamax.matrix.client;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.Optional;
|
||||
|
||||
|
||||
import okhttp3.MediaType;
|
||||
import okhttp3.Response;
|
||||
import okhttp3.ResponseBody;
|
||||
|
||||
public class MatrixHttpContentResult {
|
||||
|
||||
private final boolean valid;
|
||||
private final Map<String, List<String>> headers;
|
||||
private final Optional<String> contentType;
|
||||
private final byte[] data;
|
||||
|
||||
public MatrixHttpContentResult(Response response) throws IOException {
|
||||
try (ResponseBody body = response.body()) {
|
||||
boolean hasBody = Objects.nonNull(body);
|
||||
valid = hasBody && response.code() == 200;
|
||||
headers = response.headers().toMultimap();
|
||||
|
||||
if (hasBody) {
|
||||
contentType = Optional.ofNullable(body.contentType()).map(MediaType::toString);
|
||||
data = body.bytes();
|
||||
} else {
|
||||
contentType = Optional.empty();
|
||||
data = new byte[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
return valid;
|
||||
}
|
||||
|
||||
public Optional<List<String>> getHeader(String name) {
|
||||
return Optional.ofNullable(headers.get(name));
|
||||
}
|
||||
|
||||
public Optional<String> getContentType() {
|
||||
return contentType;
|
||||
}
|
||||
|
||||
public byte[] getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
93
src/main/java/io/kamax/matrix/client/MatrixHttpPushRule.java
Normal file
93
src/main/java/io/kamax/matrix/client/MatrixHttpPushRule.java
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* matrix-java-sdk - Matrix Client SDK for Java
|
||||
* Copyright (C) 2018 Kamax Sarl
|
||||
*
|
||||
* https://www.kamax.io/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.kamax.matrix.client;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import io.kamax.matrix.json.GsonUtil;
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
public class MatrixHttpPushRule extends AMatrixHttpClient implements _PushRule {
|
||||
|
||||
private static final String ActionKey = "actions";
|
||||
private static final String EnabledKey = "enabled";
|
||||
|
||||
private final String[] baseSegments;
|
||||
|
||||
public MatrixHttpPushRule(MatrixClientContext context, String scope, String kind, String id) {
|
||||
super(context);
|
||||
baseSegments = new String[] { "pushrules", scope, kind, id };
|
||||
}
|
||||
|
||||
private URL makeUrl() {
|
||||
return getClientPath(baseSegments);
|
||||
}
|
||||
|
||||
private URL makeUrl(String... segments) {
|
||||
return getClientPath(ArrayUtils.addAll(baseSegments, segments));
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonObject getJson() {
|
||||
return GsonUtil.parseObj(executeAuthenticated(getRequest(makeUrl())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(JsonObject data) {
|
||||
executeAuthenticated(request(makeUrl()).put(getJsonBody(data)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete() {
|
||||
executeAuthenticated(request(makeUrl()).delete());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
JsonObject response = GsonUtil.parseObj(executeAuthenticated(getRequest(makeUrl(EnabledKey))));
|
||||
return GsonUtil.getPrimitive(response, EnabledKey).getAsBoolean();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabled(boolean enabled) {
|
||||
executeAuthenticated(request(makeUrl(EnabledKey)).put(getJsonBody(GsonUtil.makeObj(EnabledKey, enabled))));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getActions() {
|
||||
JsonObject response = GsonUtil.parseObj(executeAuthenticated(getRequest(makeUrl(ActionKey))));
|
||||
return GsonUtil.asList(GsonUtil.findArray(response, ActionKey).orElseGet(JsonArray::new), String.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setActions(List<String> data) {
|
||||
executeAuthenticated(
|
||||
request(makeUrl(ActionKey)).put(getJsonBody(GsonUtil.makeObj(ActionKey, GsonUtil.asArray(data)))));
|
||||
}
|
||||
|
||||
}
|
50
src/main/java/io/kamax/matrix/client/MatrixHttpRequest.java
Normal file
50
src/main/java/io/kamax/matrix/client/MatrixHttpRequest.java
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* matrix-java-sdk - Matrix Client SDK for Java
|
||||
* Copyright (C) 2017 Kamax Sarl
|
||||
*
|
||||
* https://www.kamax.io/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.kamax.matrix.client;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
import okhttp3.Request;
|
||||
|
||||
public class MatrixHttpRequest {
|
||||
private final Request.Builder httpRequest;
|
||||
private List<Integer> ignoredErrorCodes = new ArrayList<>();
|
||||
|
||||
public MatrixHttpRequest(Request.Builder request) {
|
||||
this.httpRequest = request;
|
||||
}
|
||||
|
||||
public MatrixHttpRequest addIgnoredErrorCode(int errcode) {
|
||||
ignoredErrorCodes.add(errcode);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Request.Builder getHttpRequest() {
|
||||
return httpRequest;
|
||||
}
|
||||
|
||||
public List<Integer> getIgnoredErrorCodes() {
|
||||
return ignoredErrorCodes;
|
||||
}
|
||||
|
||||
}
|
440
src/main/java/io/kamax/matrix/client/MatrixHttpRoom.java
Normal file
440
src/main/java/io/kamax/matrix/client/MatrixHttpRoom.java
Normal file
@@ -0,0 +1,440 @@
|
||||
/*
|
||||
* matrix-java-sdk - Matrix Client SDK for Java
|
||||
* Copyright (C) 2017 Kamax Sarl
|
||||
*
|
||||
* https://www.kamax.io/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.kamax.matrix.client;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import io.kamax.matrix.MatrixErrorInfo;
|
||||
import io.kamax.matrix.MatrixID;
|
||||
import io.kamax.matrix._MatrixContent;
|
||||
import io.kamax.matrix._MatrixID;
|
||||
import io.kamax.matrix._MatrixUserProfile;
|
||||
import io.kamax.matrix.hs._MatrixRoom;
|
||||
import io.kamax.matrix.json.GsonUtil;
|
||||
import io.kamax.matrix.json.RoomMessageChunkResponseJson;
|
||||
import io.kamax.matrix.json.RoomMessageFormattedTextPutBody;
|
||||
import io.kamax.matrix.json.RoomMessageTextPutBody;
|
||||
import io.kamax.matrix.json.RoomTagSetBody;
|
||||
import io.kamax.matrix.json.event.MatrixJsonPersistentEvent;
|
||||
import io.kamax.matrix.room.*;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.Request;
|
||||
|
||||
public class MatrixHttpRoom extends AMatrixHttpClient implements _MatrixRoom {
|
||||
|
||||
private Logger log = LoggerFactory.getLogger(MatrixHttpRoom.class);
|
||||
|
||||
private String roomId;
|
||||
|
||||
public MatrixHttpRoom(MatrixClientContext context, String roomId) {
|
||||
super(context);
|
||||
this.roomId = roomId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAddress() {
|
||||
return roomId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> getName() {
|
||||
return getState("m.room.name").flatMap(obj -> GsonUtil.findString(obj, "name"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> getTopic() {
|
||||
return getState("m.room.topic").flatMap(obj -> GsonUtil.findString(obj, "topic"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> getAvatarUrl() {
|
||||
return getState("m.room.avatar").flatMap(obj -> GsonUtil.findString(obj, "url"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<_MatrixContent> getAvatar() {
|
||||
return getAvatarUrl().flatMap(url -> {
|
||||
try {
|
||||
return Optional.of(new MatrixHttpContent(context, new URI(url)));
|
||||
} catch (URISyntaxException e) {
|
||||
log.debug("{} is not a valid URI for avatar, returning empty", url);
|
||||
return Optional.empty();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return roomId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<JsonObject> getState(String type) {
|
||||
URL path = getClientPath("rooms", getAddress(), "state", type);
|
||||
|
||||
MatrixHttpRequest request = new MatrixHttpRequest(new Request.Builder().get().url(path));
|
||||
request.addIgnoredErrorCode(404);
|
||||
String body = executeAuthenticated(request);
|
||||
if (StringUtils.isBlank(body)) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
return Optional.of(GsonUtil.parseObj(body));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<JsonObject> getState(String type, String key) {
|
||||
URL path = getClientPath("rooms", roomId, "state", type, key);
|
||||
|
||||
MatrixHttpRequest request = new MatrixHttpRequest(new Request.Builder().get().url(path));
|
||||
request.addIgnoredErrorCode(404);
|
||||
String body = executeAuthenticated(request);
|
||||
if (StringUtils.isBlank(body)) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
return Optional.of(GsonUtil.parseObj(body));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void join() {
|
||||
join(Collections.emptyList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void join(List<String> servers) {
|
||||
HttpUrl.Builder b = getClientPathBuilder("rooms", roomId, "join");
|
||||
servers.forEach(server -> b.addQueryParameter("server_name", server));
|
||||
executeAuthenticated(new Request.Builder().post(getJsonBody(new JsonObject())).url(b.build()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<MatrixErrorInfo> tryJoin() {
|
||||
return tryJoin(Collections.emptyList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<MatrixErrorInfo> tryJoin(List<String> servers) {
|
||||
try {
|
||||
join(servers);
|
||||
return Optional.empty();
|
||||
} catch (MatrixClientRequestException e) {
|
||||
return e.getError();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void leave() {
|
||||
URL path = getClientPath("rooms", roomId, "leave");
|
||||
MatrixHttpRequest request = new MatrixHttpRequest(
|
||||
new Request.Builder().post(getJsonBody(new JsonObject())).url(path));
|
||||
|
||||
// TODO Find a better way to handle room objects for unknown rooms
|
||||
// Maybe throw exception?
|
||||
// TODO implement method to check room existence - isValid() ?
|
||||
// if (res.getStatusLine().getStatusCode() == 404) {
|
||||
// log.warn("Room {} is not joined, ignoring call", roomId);
|
||||
// return;
|
||||
// }
|
||||
request.addIgnoredErrorCode(404);
|
||||
executeAuthenticated(request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<MatrixErrorInfo> tryLeave() {
|
||||
try {
|
||||
leave();
|
||||
return Optional.empty();
|
||||
} catch (MatrixClientRequestException e) {
|
||||
return e.getError();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void kick(_MatrixID user) {
|
||||
kick(user, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void kick(_MatrixID user, String reason) {
|
||||
JsonObject body = new JsonObject();
|
||||
body.addProperty("user_id", user.getId());
|
||||
body.addProperty("reason", reason);
|
||||
URL path = getClientPath("rooms", roomId, "kick");
|
||||
MatrixHttpRequest request = new MatrixHttpRequest(new Request.Builder().post(getJsonBody(body)).url(path));
|
||||
executeAuthenticated(request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<MatrixErrorInfo> tryKick(_MatrixID user) {
|
||||
return tryKick(user, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<MatrixErrorInfo> tryKick(_MatrixID user, String reason) {
|
||||
try {
|
||||
kick(user, reason);
|
||||
return Optional.empty();
|
||||
} catch (MatrixClientRequestException e) {
|
||||
return e.getError();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String sendEvent(String type, JsonObject content) {
|
||||
// FIXME URL encoding
|
||||
URL path = getClientPath("rooms", roomId, "send", type, Long.toString(System.currentTimeMillis()));
|
||||
String body = executeAuthenticated(new Request.Builder().put(getJsonBody(content)).url(path));
|
||||
return GsonUtil.getStringOrThrow(GsonUtil.parseObj(body), "event_id");
|
||||
}
|
||||
|
||||
private String sendMessage(RoomMessageTextPutBody content) {
|
||||
return sendEvent("m.room.message", GsonUtil.makeObj(content));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String sendText(String message) {
|
||||
return sendMessage(new RoomMessageTextPutBody(message));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String sendFormattedText(String formatted, String rawFallback) {
|
||||
// TODO sanitize input
|
||||
return sendMessage(new RoomMessageFormattedTextPutBody(rawFallback, formatted));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String sendNotice(String message) {
|
||||
return sendMessage(new RoomMessageTextPutBody("m.notice", message));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String sendNotice(String formatted, String plain) {
|
||||
// TODO sanitize input
|
||||
return sendMessage(new RoomMessageFormattedTextPutBody("m.notice", plain, formatted));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendReceipt(String type, String eventId) {
|
||||
URL path = getClientPath("rooms", roomId, "receipt", type, eventId);
|
||||
executeAuthenticated(new Request.Builder().post(getJsonBody(new JsonObject())).url(path));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendReceipt(ReceiptType type, String eventId) {
|
||||
sendReceipt(type.getId(), eventId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendReadReceipt(String eventId) {
|
||||
sendReceipt(ReceiptType.Read, eventId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invite(_MatrixID mxId) {
|
||||
URL path = getClientPath("rooms", roomId, "invite");
|
||||
executeAuthenticated(
|
||||
new Request.Builder().post(getJsonBody(GsonUtil.makeObj("user_id", mxId.getId()))).url(path));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<_MatrixUserProfile> getJoinedUsers() {
|
||||
URL path = getClientPath("rooms", roomId, "joined_members");
|
||||
String body = executeAuthenticated(new Request.Builder().get().url(path));
|
||||
|
||||
List<_MatrixUserProfile> ids = new ArrayList<>();
|
||||
if (StringUtils.isNotEmpty(body)) {
|
||||
JsonObject joinedUsers = jsonParser.parse(body).getAsJsonObject().get("joined").getAsJsonObject();
|
||||
ids = joinedUsers.entrySet().stream().filter(e -> e.getValue().isJsonObject()).map(entry -> {
|
||||
JsonObject obj = entry.getValue().getAsJsonObject();
|
||||
return new MatrixHttpUser(getContext(), MatrixID.asAcceptable(entry.getKey())) {
|
||||
|
||||
@Override
|
||||
public Optional<String> getName() {
|
||||
return GsonUtil.findString(obj, "display_name");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<_MatrixContent> getAvatar() {
|
||||
return GsonUtil.findString(obj, "avatar_url").flatMap(s -> {
|
||||
try {
|
||||
return Optional.of(new URI(s));
|
||||
} catch (URISyntaxException e) {
|
||||
return Optional.empty();
|
||||
}
|
||||
}).map(uri -> new MatrixHttpContent(getContext(), uri));
|
||||
}
|
||||
|
||||
};
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
return ids;
|
||||
}
|
||||
|
||||
@Override
|
||||
public _MatrixRoomMessageChunk getMessages(_MatrixRoomMessageChunkOptions options) {
|
||||
HttpUrl.Builder builder = getClientPathBuilder("rooms", roomId, "messages");
|
||||
builder.addQueryParameter("from", options.getFromToken());
|
||||
builder.addQueryParameter("dir", options.getDirection());
|
||||
options.getToToken().ifPresent(token -> builder.addQueryParameter("to", token));
|
||||
options.getLimit().ifPresent(limit -> builder.addQueryParameter("limit", limit.toString()));
|
||||
|
||||
String bodyRaw = executeAuthenticated(new Request.Builder().get().url(builder.build().url()));
|
||||
RoomMessageChunkResponseJson body = GsonUtil.get().fromJson(bodyRaw, RoomMessageChunkResponseJson.class);
|
||||
return new MatrixRoomMessageChunk(body.getStart(), body.getEnd(),
|
||||
body.getChunk().stream().map(MatrixJsonPersistentEvent::new).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Tag> getUserTags() {
|
||||
return getAllTags().stream().filter(tag -> "u".equals(tag.getNamespace()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Tag> getAllTags() {
|
||||
|
||||
URL path = getClientPath("user", getUserId(), "rooms", getAddress(), "tags");
|
||||
|
||||
String body = executeAuthenticated(new Request.Builder().get().url(path));
|
||||
|
||||
JsonObject jsonTags = GsonUtil.parseObj(body).getAsJsonObject("tags").getAsJsonObject();
|
||||
List<Tag> tags = jsonTags.entrySet().stream().map(entry -> {
|
||||
String completeName = entry.getKey();
|
||||
String name = "";
|
||||
String namespace = "";
|
||||
if (completeName.startsWith("m.")) {
|
||||
name = completeName.substring(2);
|
||||
namespace = "m";
|
||||
} else if (completeName.startsWith("u.")) {
|
||||
name = completeName.substring(2);
|
||||
namespace = "u";
|
||||
} else {
|
||||
name = completeName;
|
||||
}
|
||||
JsonElement jsonOrder = entry.getValue().getAsJsonObject().get("order");
|
||||
Double order = null;
|
||||
if (jsonOrder != null) {
|
||||
order = jsonOrder.getAsDouble();
|
||||
}
|
||||
|
||||
return new Tag(namespace, name, order);
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
return tags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addUserTag(String tag) {
|
||||
addTag("u." + tag, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addUserTag(String tag, double order) {
|
||||
addTag("u." + tag, order);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteUserTag(String tag) {
|
||||
deleteTag("u." + tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFavouriteTag() {
|
||||
addTag("m.favourite", null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFavouriteTag(double order) {
|
||||
addTag("m.favourite", order);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Tag> getFavouriteTag() {
|
||||
return getAllTags().stream()
|
||||
.filter(tag -> "m".equals(tag.getNamespace()) && "favourite".equals(tag.getName())).findFirst();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteFavouriteTag() {
|
||||
deleteTag("m.favourite");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addLowpriorityTag() {
|
||||
addTag("m.lowpriority", null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addLowpriorityTag(double order) {
|
||||
addTag("m.lowpriority", order);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Tag> getLowpriorityTag() {
|
||||
return getAllTags().stream()
|
||||
.filter(tag -> "m".equals(tag.getNamespace()) && "lowpriority".equals(tag.getName())).findFirst();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteLowpriorityTag() {
|
||||
deleteTag("m.lowpriority");
|
||||
}
|
||||
|
||||
private void addTag(String tag, Double order) {
|
||||
// TODO check name size
|
||||
|
||||
if (order != null && (order < 0 || order > 1)) {
|
||||
throw new IllegalArgumentException("Order out of range!");
|
||||
}
|
||||
|
||||
URL path = getClientPath("user", getUserId(), "rooms", getAddress(), "tags", tag);
|
||||
Request.Builder request = new Request.Builder().url(path);
|
||||
if (order != null) {
|
||||
request.put(getJsonBody(new RoomTagSetBody(order)));
|
||||
} else {
|
||||
request.put(getJsonBody(new JsonObject()));
|
||||
}
|
||||
executeAuthenticated(request);
|
||||
}
|
||||
|
||||
private void deleteTag(String tag) {
|
||||
URL path = getClientPath("user", getUserId(), "rooms", getAddress(), "tags", tag);
|
||||
executeAuthenticated(new Request.Builder().url(path).delete());
|
||||
}
|
||||
}
|
125
src/main/java/io/kamax/matrix/client/MatrixHttpUser.java
Normal file
125
src/main/java/io/kamax/matrix/client/MatrixHttpUser.java
Normal file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* matrix-java-sdk - Matrix Client SDK for Java
|
||||
* Copyright (C) 2017 Kamax Sarl
|
||||
*
|
||||
* https://www.kamax.io/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.kamax.matrix.client;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import io.kamax.matrix._MatrixContent;
|
||||
import io.kamax.matrix._MatrixID;
|
||||
import io.kamax.matrix._MatrixUser;
|
||||
import io.kamax.matrix.client.regular.Presence;
|
||||
import io.kamax.matrix.json.GsonUtil;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.util.Optional;
|
||||
|
||||
|
||||
import okhttp3.Request;
|
||||
|
||||
public class MatrixHttpUser extends AMatrixHttpClient implements _MatrixUser {
|
||||
|
||||
private Logger log = LoggerFactory.getLogger(MatrixHttpUser.class);
|
||||
|
||||
private _MatrixID mxId;
|
||||
|
||||
public MatrixHttpUser(MatrixClientContext context, _MatrixID mxId) {
|
||||
super(context);
|
||||
|
||||
this.mxId = mxId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public _MatrixID getId() {
|
||||
return mxId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> getName() {
|
||||
URL path = getClientPath("profile", mxId.getId(), "displayname");
|
||||
|
||||
MatrixHttpRequest request = new MatrixHttpRequest(new Request.Builder().get().url(path));
|
||||
request.addIgnoredErrorCode(404);
|
||||
String body = executeAuthenticated(request);
|
||||
return extractAsStringFromBody(body, "displayname");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setName(String name) {
|
||||
URL path = getClientPath("profile", mxId.getId(), "displayname");
|
||||
JsonObject body = GsonUtil.makeObj("displayname", name);
|
||||
executeAuthenticated(new Request.Builder().put(getJsonBody(body)).url(path));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> getAvatarUrl() {
|
||||
URL path = getClientPath("profile", mxId.getId(), "avatar_url");
|
||||
|
||||
MatrixHttpRequest request = new MatrixHttpRequest(new Request.Builder().get().url(path));
|
||||
request.addIgnoredErrorCode(404);
|
||||
String body = executeAuthenticated(request);
|
||||
return extractAsStringFromBody(body, "avatar_url");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAvatar(String avatarRef) {
|
||||
URL path = getClientPath("profile", mxId.getId(), "avatar_url");
|
||||
JsonObject body = GsonUtil.makeObj("avatar_url", avatarRef);
|
||||
executeAuthenticated(new Request.Builder().put(getJsonBody(body)).url(path));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAvatar(URI avatarUri) {
|
||||
setAvatar(avatarUri.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<_MatrixContent> getAvatar() {
|
||||
return getAvatarUrl().flatMap(uri -> {
|
||||
try {
|
||||
return Optional.of(new MatrixHttpContent(getContext(), new URI(uri)));
|
||||
} catch (URISyntaxException e) {
|
||||
log.debug("{} is not a valid URI for avatar, returning empty", uri);
|
||||
return Optional.empty();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<_Presence> getPresence() {
|
||||
URL path = getClientPath("presence", mxId.getId(), "status");
|
||||
|
||||
MatrixHttpRequest request = new MatrixHttpRequest(new Request.Builder().get().url(path));
|
||||
request.addIgnoredErrorCode(404);
|
||||
String body = execute(request);
|
||||
if (StringUtils.isBlank(body)) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
return Optional.of(new Presence(GsonUtil.parseObj(body)));
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* matrix-java-sdk - Matrix Client SDK for Java
|
||||
* Copyright (C) 2017 Kamax Sarl
|
||||
*
|
||||
* https://www.kamax.io/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.kamax.matrix.client;
|
||||
|
||||
public class MatrixPasswordCredentials {
|
||||
private final String localPart;
|
||||
private final String password;
|
||||
|
||||
public MatrixPasswordCredentials(String localPart, String password) {
|
||||
this.localPart = localPart;
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public String getLocalPart() {
|
||||
return localPart;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
}
|
45
src/main/java/io/kamax/matrix/client/PresenceStatus.java
Normal file
45
src/main/java/io/kamax/matrix/client/PresenceStatus.java
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* matrix-java-sdk - Matrix Client SDK for Java
|
||||
* Copyright (C) 2018 Kamax Sàrl
|
||||
*
|
||||
* https://www.kamax.io/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.kamax.matrix.client;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
public enum PresenceStatus {
|
||||
|
||||
Online("online"),
|
||||
Offline("offline"),
|
||||
Unavailable("unavailable");
|
||||
|
||||
private String id;
|
||||
|
||||
PresenceStatus(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public boolean is(String status) {
|
||||
return StringUtils.equals(id, status);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* matrix-java-sdk - Matrix Client SDK for Java
|
||||
* Copyright (C) 2018 Kamax Sarl
|
||||
*
|
||||
* https://www.kamax.io/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.kamax.matrix.client;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
|
||||
import io.kamax.matrix.json.GsonUtil;
|
||||
import io.kamax.matrix.json.InvalidJsonException;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public class WellKnownAutoDiscoverySettings implements _AutoDiscoverySettings {
|
||||
|
||||
private final Logger log = LoggerFactory.getLogger(WellKnownAutoDiscoverySettings.class);
|
||||
|
||||
private JsonObject raw;
|
||||
|
||||
private List<URL> hsBaseUrls = new ArrayList<>();
|
||||
private List<URL> isBaseUrls = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Build .well-known auto-discovery settings from a .well-known source.
|
||||
*
|
||||
* @param raw
|
||||
* The raw JSON data
|
||||
* @throws IllegalArgumentException
|
||||
* if the data is invalid and couldn't be parsed.
|
||||
*/
|
||||
public WellKnownAutoDiscoverySettings(String raw) {
|
||||
try {
|
||||
setRaw(GsonUtil.parseObj(raw));
|
||||
} catch (JsonParseException | InvalidJsonException e) {
|
||||
throw new IllegalArgumentException("Invalid JSON data for .well-known string");
|
||||
}
|
||||
}
|
||||
|
||||
private void setRaw(JsonObject raw) {
|
||||
this.raw = raw;
|
||||
process();
|
||||
}
|
||||
|
||||
private Optional<URL> getUrl(String url) {
|
||||
try {
|
||||
return Optional.of(new URL(url));
|
||||
} catch (MalformedURLException e) {
|
||||
log.warn("Ignoring invalid Base URL entry in well-known: {} - {}", url, e.getMessage());
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
private List<URL> getUrls(JsonArray array) {
|
||||
List<URL> urls = new ArrayList<>();
|
||||
|
||||
array.forEach(el -> {
|
||||
if (!el.isJsonPrimitive()) {
|
||||
log.warn("Ignoring invalid Base URL entry in well-known: {} - Not a string", GsonUtil.get().toJson(el));
|
||||
return;
|
||||
}
|
||||
|
||||
getUrl(el.getAsString()).ifPresent(urls::add);
|
||||
});
|
||||
|
||||
return urls;
|
||||
}
|
||||
|
||||
private List<URL> processUrls(JsonObject base, String key) {
|
||||
List<URL> urls = new ArrayList<>();
|
||||
|
||||
GsonUtil.findObj(base, key).ifPresent(cfg -> {
|
||||
log.info("Found data");
|
||||
|
||||
GsonUtil.findArray(cfg, "base_urls").ifPresent(arr -> {
|
||||
log.info("Found base URL(s)");
|
||||
urls.addAll(getUrls(arr));
|
||||
});
|
||||
|
||||
if (urls.isEmpty()) {
|
||||
GsonUtil.findString(cfg, "base_url").flatMap(this::getUrl).ifPresent(urls::add);
|
||||
}
|
||||
});
|
||||
|
||||
return urls;
|
||||
}
|
||||
|
||||
private void process() {
|
||||
log.info("Processing Homeserver Base URLs");
|
||||
hsBaseUrls = processUrls(raw, "m.homeserver");
|
||||
log.info("Found {} valid URL(s)", hsBaseUrls.size());
|
||||
|
||||
log.info("Processing Identity server Base URLs");
|
||||
isBaseUrls = processUrls(raw, "m.identity_server");
|
||||
log.info("Found {} valid URL(s)", isBaseUrls.size());
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonObject getRaw() {
|
||||
return raw;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<URL> getHsBaseUrls() {
|
||||
return Collections.unmodifiableList(hsBaseUrls);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<URL> getIsBaseUrls() {
|
||||
return Collections.unmodifiableList(isBaseUrls);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* matrix-java-sdk - Matrix Client SDK for Java
|
||||
* Copyright (C) 2018 Kamax Sarl
|
||||
*
|
||||
* https://www.kamax.io/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.kamax.matrix.client;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.List;
|
||||
|
||||
public interface _AutoDiscoverySettings {
|
||||
|
||||
JsonObject getRaw();
|
||||
|
||||
List<URL> getHsBaseUrls();
|
||||
|
||||
List<URL> getIsBaseUrls();
|
||||
|
||||
}
|
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* matrix-java-sdk - Matrix Client SDK for Java
|
||||
* Copyright (C) 2018 Kamax Sarl
|
||||
*
|
||||
* https://www.kamax.io/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.kamax.matrix.client;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface _GlobalPushRulesSet {
|
||||
|
||||
List<JsonObject> getContent();
|
||||
|
||||
List<JsonObject> getOverride();
|
||||
|
||||
List<JsonObject> getRoom();
|
||||
|
||||
List<JsonObject> getSender();
|
||||
|
||||
List<JsonObject> getUnderride();
|
||||
|
||||
}
|
158
src/main/java/io/kamax/matrix/client/_MatrixClient.java
Normal file
158
src/main/java/io/kamax/matrix/client/_MatrixClient.java
Normal file
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* matrix-java-sdk - Matrix Client SDK for Java
|
||||
* Copyright (C) 2017 Kamax Sarl
|
||||
*
|
||||
* https://www.kamax.io/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.kamax.matrix.client;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import io.kamax.matrix._MatrixContent;
|
||||
import io.kamax.matrix._MatrixID;
|
||||
import io.kamax.matrix._MatrixUser;
|
||||
import io.kamax.matrix.hs._MatrixRoom;
|
||||
import io.kamax.matrix.room.RoomAlias;
|
||||
import io.kamax.matrix.room._RoomAliasLookup;
|
||||
import io.kamax.matrix.room._RoomCreationOptions;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public interface _MatrixClient extends _MatrixClientRaw {
|
||||
|
||||
_MatrixID getWhoAmI();
|
||||
|
||||
void setDisplayName(String name);
|
||||
|
||||
_RoomAliasLookup lookup(RoomAlias alias);
|
||||
|
||||
_MatrixRoom createRoom(_RoomCreationOptions options);
|
||||
|
||||
_MatrixRoom getRoom(String roomId);
|
||||
|
||||
List<_MatrixRoom> getJoinedRooms();
|
||||
|
||||
_MatrixRoom joinRoom(String roomIdOrAlias);
|
||||
|
||||
_MatrixUser getUser(_MatrixID mxId);
|
||||
|
||||
Optional<String> getDeviceId();
|
||||
|
||||
/* Custom endpoint! */
|
||||
// TODO refactor into custom synapse class?
|
||||
void register(MatrixPasswordCredentials credentials, String sharedSecret, boolean admin);
|
||||
|
||||
/***
|
||||
* Set the access token to use for any authenticated API calls.
|
||||
*
|
||||
* @param accessToken
|
||||
* The access token provided by the server which must be valid
|
||||
* @throws MatrixClientRequestException
|
||||
* If an error occurred while checking for the identity behind the access token
|
||||
*/
|
||||
void setAccessToken(String accessToken) throws MatrixClientRequestException;
|
||||
|
||||
void login(MatrixPasswordCredentials credentials);
|
||||
|
||||
void logout();
|
||||
|
||||
_SyncData sync(_SyncOptions options);
|
||||
|
||||
/**
|
||||
* Download content from the media repository
|
||||
*
|
||||
* @param mxUri
|
||||
* The MXC URI for the content to download
|
||||
* @return The content
|
||||
* @throws IllegalArgumentException
|
||||
* if the parameter is not a valid MXC URI
|
||||
*/
|
||||
_MatrixContent getMedia(String mxUri) throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Download content from the media repository
|
||||
*
|
||||
* @param mxUri
|
||||
* The MXC URI for the content to download
|
||||
* @return The content
|
||||
* @throws IllegalArgumentException
|
||||
* if the parameter is not a valid MXC URI
|
||||
*/
|
||||
_MatrixContent getMedia(URI mxUri) throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Upload content to the media repository
|
||||
*
|
||||
* @param data
|
||||
* The data to send
|
||||
* @param type
|
||||
* The mime-type of the content upload
|
||||
* @return The MXC URI for the uploaded content
|
||||
*/
|
||||
String putMedia(byte[] data, String type);
|
||||
|
||||
/**
|
||||
* Upload content to the media repository
|
||||
*
|
||||
* @param data
|
||||
* The data to send
|
||||
* @param type
|
||||
* The mime-type of the content upload
|
||||
* @param filename
|
||||
* A suggested filename for the content
|
||||
* @return The MXC URI for the uploaded content
|
||||
*/
|
||||
String putMedia(byte[] data, String type, String filename);
|
||||
|
||||
/**
|
||||
* Upload content to the media repository
|
||||
*
|
||||
* @param data
|
||||
* The file to read the data from
|
||||
* @param type
|
||||
* The mime-type of the content upload
|
||||
* @return The MXC URI for the uploaded content
|
||||
*/
|
||||
String putMedia(File data, String type);
|
||||
|
||||
/**
|
||||
* Upload content to the media repository
|
||||
*
|
||||
* @param data
|
||||
* The data to send
|
||||
* @param type
|
||||
* The mime-type of the content upload
|
||||
* @param filename
|
||||
* A suggested filename for the content
|
||||
* @return The MXC URI for the uploaded content
|
||||
*/
|
||||
String putMedia(File data, String type, String filename);
|
||||
|
||||
List<JsonObject> getPushers();
|
||||
|
||||
void setPusher(JsonObject pusher);
|
||||
|
||||
void deletePusher(String pushKey);
|
||||
|
||||
_GlobalPushRulesSet getPushRules();
|
||||
|
||||
_PushRule getPushRule(String scope, String kind, String id);
|
||||
|
||||
}
|
51
src/main/java/io/kamax/matrix/client/_MatrixClientRaw.java
Normal file
51
src/main/java/io/kamax/matrix/client/_MatrixClientRaw.java
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* matrix-java-sdk - Matrix Client SDK for Java
|
||||
* Copyright (C) 2017 Kamax Sarl
|
||||
*
|
||||
* https://www.kamax.io/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.kamax.matrix.client;
|
||||
|
||||
import io.kamax.matrix._MatrixID;
|
||||
import io.kamax.matrix.hs._MatrixHomeserver;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public interface _MatrixClientRaw {
|
||||
|
||||
MatrixClientContext getContext();
|
||||
|
||||
_MatrixHomeserver getHomeserver();
|
||||
|
||||
Optional<String> getAccessToken();
|
||||
|
||||
Optional<_MatrixID> getUser();
|
||||
|
||||
Optional<_AutoDiscoverySettings> discoverSettings();
|
||||
|
||||
// FIXME
|
||||
// we should maybe have a dedicated object for HS related items and be merged into getHomeserver() which is only
|
||||
// holding state at this point and is not functional
|
||||
List<String> getHomeApiVersions();
|
||||
|
||||
// FIXME
|
||||
// we should maybe have a dedicated object for IS related items. Will reconsider when implementing
|
||||
// other part of the IS API
|
||||
boolean validateIsBaseUrl();
|
||||
|
||||
}
|
29
src/main/java/io/kamax/matrix/client/_Presence.java
Normal file
29
src/main/java/io/kamax/matrix/client/_Presence.java
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* matrix-java-sdk - Matrix Client SDK for Java
|
||||
* Copyright (C) 2018 Kamax Sàrl
|
||||
*
|
||||
* https://www.kamax.io/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.kamax.matrix.client;
|
||||
|
||||
public interface _Presence {
|
||||
|
||||
String getStatus();
|
||||
|
||||
Long getLastActive();
|
||||
|
||||
}
|
43
src/main/java/io/kamax/matrix/client/_PushRule.java
Normal file
43
src/main/java/io/kamax/matrix/client/_PushRule.java
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* matrix-java-sdk - Matrix Client SDK for Java
|
||||
* Copyright (C) 2018 Kamax Sarl
|
||||
*
|
||||
* https://www.kamax.io/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.kamax.matrix.client;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface _PushRule {
|
||||
|
||||
JsonObject getJson();
|
||||
|
||||
void set(JsonObject data);
|
||||
|
||||
void delete();
|
||||
|
||||
boolean isEnabled();
|
||||
|
||||
void setEnabled(boolean enabled);
|
||||
|
||||
List<String> getActions();
|
||||
|
||||
void setActions(List<String> data);
|
||||
|
||||
}
|
253
src/main/java/io/kamax/matrix/client/_SyncData.java
Normal file
253
src/main/java/io/kamax/matrix/client/_SyncData.java
Normal file
@@ -0,0 +1,253 @@
|
||||
/*
|
||||
* matrix-java-sdk - Matrix Client SDK for Java
|
||||
* Copyright (C) 2018 Kamax Sarl
|
||||
*
|
||||
* https://www.kamax.io/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.kamax.matrix.client;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import io.kamax.matrix.event._MatrixAccountDataEvent;
|
||||
import io.kamax.matrix.event._MatrixEphemeralEvent;
|
||||
import io.kamax.matrix.event._MatrixPersistentEvent;
|
||||
import io.kamax.matrix.event._MatrixStateEvent;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Representation of the data when performing a sync call on the Matrix Client API.
|
||||
*/
|
||||
public interface _SyncData {
|
||||
|
||||
interface State {
|
||||
|
||||
/**
|
||||
* The state of the room.
|
||||
*
|
||||
* @return a list of state events.
|
||||
*/
|
||||
List<_MatrixStateEvent> getEvents();
|
||||
|
||||
}
|
||||
|
||||
interface Timeline {
|
||||
|
||||
/**
|
||||
* Events that happened in the sync window.
|
||||
*
|
||||
* @return List of events.
|
||||
*/
|
||||
List<_MatrixPersistentEvent> getEvents();
|
||||
|
||||
/**
|
||||
* If the number of events returned was limited by the sync filter.
|
||||
*
|
||||
* @return true if the number of events was limited, false if not.
|
||||
*/
|
||||
boolean isLimited();
|
||||
|
||||
/**
|
||||
* Token that can be supplied to fetch previous events for the associated room.
|
||||
*
|
||||
* @return the token.
|
||||
*/
|
||||
String getPreviousBatchToken();
|
||||
}
|
||||
|
||||
interface Ephemeral {
|
||||
|
||||
/**
|
||||
* Events that happened in the sync window.
|
||||
*
|
||||
* @return List of events.
|
||||
*/
|
||||
List<_MatrixEphemeralEvent> getEvents();
|
||||
}
|
||||
|
||||
interface AccountData {
|
||||
|
||||
/**
|
||||
* Events that happened in the sync window.
|
||||
*
|
||||
* @return List of events.
|
||||
*/
|
||||
List<_MatrixAccountDataEvent> getEvents();
|
||||
}
|
||||
|
||||
interface InvitedRoom {
|
||||
|
||||
/**
|
||||
* The ID of the room the user was invited to.
|
||||
*
|
||||
* @return the room ID.
|
||||
*/
|
||||
String getId();
|
||||
|
||||
/**
|
||||
* The state of the room at the invite event.
|
||||
*
|
||||
* @return a list of state events.
|
||||
*/
|
||||
State getState();
|
||||
|
||||
}
|
||||
|
||||
interface UnreadNotifications {
|
||||
|
||||
/**
|
||||
* The number of unread notifications with the highlight flag set.
|
||||
*
|
||||
* @return the count.
|
||||
*/
|
||||
long getHighlightCount();
|
||||
|
||||
/**
|
||||
* The total number of unread notifications.
|
||||
*
|
||||
* @return the count.
|
||||
*/
|
||||
long getNotificationCount();
|
||||
|
||||
}
|
||||
|
||||
interface JoinedRoom {
|
||||
|
||||
/**
|
||||
* The ID of the room the user is joined to.
|
||||
*
|
||||
* @return the room id.
|
||||
*/
|
||||
String getId();
|
||||
|
||||
/**
|
||||
* State changes prior the start of the timeline.
|
||||
*
|
||||
* @return a list of state events.
|
||||
*/
|
||||
State getState();
|
||||
|
||||
/**
|
||||
* The room timeline for this sync batch.
|
||||
*
|
||||
* @return the timeline.
|
||||
*/
|
||||
Timeline getTimeline();
|
||||
|
||||
/**
|
||||
* Ephemeral events of the room.
|
||||
*
|
||||
* @return a list of ephemeral events.
|
||||
*/
|
||||
Ephemeral getEphemeral();
|
||||
|
||||
/**
|
||||
* Account events of the room.
|
||||
*
|
||||
* @return a list of account data events.
|
||||
*/
|
||||
AccountData getAccountData();
|
||||
|
||||
/**
|
||||
* The Counts of unread notifications.
|
||||
*
|
||||
* @return unread notifications.
|
||||
*/
|
||||
UnreadNotifications getUnreadNotifications();
|
||||
|
||||
}
|
||||
|
||||
interface LeftRoom {
|
||||
|
||||
/**
|
||||
* The ID of the room the user is joined to.
|
||||
*
|
||||
* @return the room id.
|
||||
*/
|
||||
String getId();
|
||||
|
||||
/**
|
||||
* State changes prior the start of the timeline.
|
||||
*
|
||||
* @return a list of state events.
|
||||
*/
|
||||
State getState();
|
||||
|
||||
/**
|
||||
* The room timeline up to the leave event.
|
||||
*
|
||||
* @return the timeline.
|
||||
*/
|
||||
Timeline getTimeline();
|
||||
|
||||
}
|
||||
|
||||
interface Rooms {
|
||||
|
||||
/**
|
||||
* Rooms the user was invited to within this sync window.
|
||||
*
|
||||
* @return Set of InvitedRoom objects.
|
||||
*/
|
||||
Set<InvitedRoom> getInvited();
|
||||
|
||||
/**
|
||||
* Rooms the user was joined in within this sync window.
|
||||
*
|
||||
* @return Set of JoinedRoom objects.
|
||||
*/
|
||||
Set<JoinedRoom> getJoined();
|
||||
|
||||
/**
|
||||
* Rooms the user left from within this sync window.
|
||||
*
|
||||
* @return Set of LeftRoom objects.
|
||||
*/
|
||||
Set<LeftRoom> getLeft();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The batch token to supply in the next sync call.
|
||||
*
|
||||
* @return the batch token.
|
||||
*/
|
||||
String nextBatchToken();
|
||||
|
||||
/**
|
||||
* The global private data created by this user.
|
||||
*
|
||||
* @return the account data.
|
||||
*/
|
||||
AccountData getAccountData();
|
||||
|
||||
/**
|
||||
* Update to the rooms.
|
||||
*
|
||||
* @return rooms object.
|
||||
*/
|
||||
Rooms getRooms();
|
||||
|
||||
/**
|
||||
* The raw JSON data for this object.
|
||||
*
|
||||
* @return the JSON data.
|
||||
*/
|
||||
JsonObject getJson();
|
||||
|
||||
}
|
65
src/main/java/io/kamax/matrix/client/_SyncOptions.java
Normal file
65
src/main/java/io/kamax/matrix/client/_SyncOptions.java
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* matrix-java-sdk - Matrix Client SDK for Java
|
||||
* Copyright (C) 2018 Kamax Sarl
|
||||
*
|
||||
* https://www.kamax.io/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.kamax.matrix.client;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Possible options that can be passed to the sync call.
|
||||
*/
|
||||
public interface _SyncOptions {
|
||||
|
||||
/**
|
||||
* The point of time to continue the sync from.
|
||||
*
|
||||
* @return A token that was provided in a previous sync call, if set.
|
||||
*/
|
||||
Optional<String> getSince();
|
||||
|
||||
/**
|
||||
* The filter to use for the sync.
|
||||
*
|
||||
* @return The ID or raw JSON filter, if set.
|
||||
*/
|
||||
Optional<String> getFilter();
|
||||
|
||||
/**
|
||||
* If the full state should be included in the sync.
|
||||
*
|
||||
* @return The full state option, if set.
|
||||
*/
|
||||
Optional<Boolean> withFullState();
|
||||
|
||||
/**
|
||||
* If the client should automatically be marked as online.
|
||||
*
|
||||
* @return The set presence option, if set.
|
||||
*/
|
||||
Optional<String> getSetPresence();
|
||||
|
||||
/**
|
||||
* The maximum time to wait, in milliseconds, before ending the sync call.
|
||||
*
|
||||
* @return The timeout option, if set.
|
||||
*/
|
||||
Optional<Long> getTimeout();
|
||||
|
||||
}
|
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* matrix-java-sdk - Matrix Client SDK for Java
|
||||
* Copyright (C) 2017 Kamax Sarl
|
||||
*
|
||||
* https://www.kamax.io/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.kamax.matrix.client.as;
|
||||
|
||||
import io.kamax.matrix.client.MatrixClientContext;
|
||||
import io.kamax.matrix.client.MatrixClientDefaults;
|
||||
import io.kamax.matrix.client._MatrixClient;
|
||||
import io.kamax.matrix.client.regular.MatrixHttpClient;
|
||||
import io.kamax.matrix.json.VirtualUserRegistrationBody;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
|
||||
public class MatrixApplicationServiceClient extends MatrixHttpClient implements _MatrixApplicationServiceClient {
|
||||
|
||||
private Logger log = LoggerFactory.getLogger(MatrixApplicationServiceClient.class);
|
||||
|
||||
public MatrixApplicationServiceClient(String domain) {
|
||||
super(domain);
|
||||
}
|
||||
|
||||
public MatrixApplicationServiceClient(URL hsBaseUrl) {
|
||||
super(hsBaseUrl);
|
||||
}
|
||||
|
||||
public MatrixApplicationServiceClient(MatrixClientContext context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public MatrixApplicationServiceClient(MatrixClientContext context, OkHttpClient.Builder client) {
|
||||
super(context, client);
|
||||
}
|
||||
|
||||
public MatrixApplicationServiceClient(MatrixClientContext context, OkHttpClient.Builder client,
|
||||
MatrixClientDefaults defaults) {
|
||||
super(context, client, defaults);
|
||||
}
|
||||
|
||||
public MatrixApplicationServiceClient(MatrixClientContext context, OkHttpClient client) {
|
||||
super(context, client);
|
||||
}
|
||||
|
||||
private MatrixHttpClient createClient(String localpart) {
|
||||
MatrixClientContext context = new MatrixClientContext(getContext()).setUserWithLocalpart(localpart)
|
||||
.setVirtual(true);
|
||||
return new MatrixHttpClient(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public _MatrixClient createUser(String localpart) {
|
||||
log.debug("Creating new user {}", localpart);
|
||||
URL path = getClientPath("register");
|
||||
executeAuthenticated(
|
||||
new Request.Builder().post(getJsonBody(new VirtualUserRegistrationBody(localpart))).url(path));
|
||||
return createClient(localpart);
|
||||
}
|
||||
|
||||
@Override
|
||||
public _MatrixClient getUser(String localpart) {
|
||||
return createClient(localpart);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* matrix-java-sdk - Matrix Client SDK for Java
|
||||
* Copyright (C) 2017 Kamax Sarl
|
||||
*
|
||||
* https://www.kamax.io/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.kamax.matrix.client.as;
|
||||
|
||||
import io.kamax.matrix.client._MatrixClient;
|
||||
|
||||
public interface _MatrixApplicationServiceClient extends _MatrixClient {
|
||||
|
||||
_MatrixClient createUser(String localpart);
|
||||
|
||||
_MatrixClient getUser(String localpart);
|
||||
|
||||
}
|
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* matrix-java-sdk - Matrix Client SDK for Java
|
||||
* Copyright (C) 2018 Kamax Sarl
|
||||
*
|
||||
* https://www.kamax.io/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.kamax.matrix.client.regular;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import io.kamax.matrix.client._GlobalPushRulesSet;
|
||||
import io.kamax.matrix.json.GsonUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class GlobalPushRulesSet implements _GlobalPushRulesSet {
|
||||
|
||||
private JsonObject data;
|
||||
|
||||
public GlobalPushRulesSet(JsonObject data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
private List<JsonObject> getForKey(String key) {
|
||||
return GsonUtil.asList(GsonUtil.findArray(data, key).orElseGet(JsonArray::new), JsonObject.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<JsonObject> getContent() {
|
||||
return getForKey("content");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<JsonObject> getOverride() {
|
||||
return getForKey("override");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<JsonObject> getRoom() {
|
||||
return getForKey("room");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<JsonObject> getSender() {
|
||||
return getForKey("sender");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<JsonObject> getUnderride() {
|
||||
return getForKey("underride");
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,292 @@
|
||||
/*
|
||||
* matrix-java-sdk - Matrix Client SDK for Java
|
||||
* Copyright (C) 2017 Kamax Sarl
|
||||
*
|
||||
* https://www.kamax.io/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.kamax.matrix.client.regular;
|
||||
|
||||
import com.google.gson.JsonNull;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import io.kamax.matrix.MatrixID;
|
||||
import io.kamax.matrix._MatrixContent;
|
||||
import io.kamax.matrix._MatrixID;
|
||||
import io.kamax.matrix._MatrixUser;
|
||||
import io.kamax.matrix.client.*;
|
||||
import io.kamax.matrix.hs._MatrixRoom;
|
||||
import io.kamax.matrix.json.*;
|
||||
import io.kamax.matrix.room.RoomAlias;
|
||||
import io.kamax.matrix.room.RoomAliasLookup;
|
||||
import io.kamax.matrix.room._RoomAliasLookup;
|
||||
import io.kamax.matrix.room._RoomCreationOptions;
|
||||
|
||||
import org.apache.commons.codec.digest.HmacAlgorithms;
|
||||
import org.apache.commons.codec.digest.HmacUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
import okhttp3.*;
|
||||
|
||||
public class MatrixHttpClient extends AMatrixHttpClient implements _MatrixClient {
|
||||
|
||||
private Logger log = LoggerFactory.getLogger(MatrixHttpClient.class);
|
||||
|
||||
public MatrixHttpClient(String domain) {
|
||||
super(domain);
|
||||
}
|
||||
|
||||
public MatrixHttpClient(URL hsBaseUrl) {
|
||||
super(hsBaseUrl);
|
||||
}
|
||||
|
||||
public MatrixHttpClient(MatrixClientContext context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public MatrixHttpClient(MatrixClientContext context, OkHttpClient.Builder client) {
|
||||
super(context, client);
|
||||
}
|
||||
|
||||
public MatrixHttpClient(MatrixClientContext context, OkHttpClient.Builder client, MatrixClientDefaults defaults) {
|
||||
super(context, client, defaults);
|
||||
}
|
||||
|
||||
public MatrixHttpClient(MatrixClientContext context, OkHttpClient client) {
|
||||
super(context, client);
|
||||
}
|
||||
|
||||
protected _MatrixID getIdentity(String token) {
|
||||
URL path = getClientPath("account", "whoami");
|
||||
String body = executeAuthenticated(new Request.Builder().get().url(path), token);
|
||||
return MatrixID.from(GsonUtil.getStringOrThrow(GsonUtil.parseObj(body), "user_id")).acceptable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public _MatrixID getWhoAmI() {
|
||||
URL path = getClientPath("account", "whoami");
|
||||
String body = executeAuthenticated(new Request.Builder().get().url(path));
|
||||
return MatrixID.from(GsonUtil.getStringOrThrow(GsonUtil.parseObj(body), "user_id")).acceptable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDisplayName(String name) {
|
||||
URL path = getClientPath("profile", getUserId(), "displayname");
|
||||
execute(new Request.Builder().put(getJsonBody(new UserDisplaynameSetBody(name))).url(path));
|
||||
}
|
||||
|
||||
@Override
|
||||
public _RoomAliasLookup lookup(RoomAlias alias) {
|
||||
URL path = getClientPath("directory", "room", alias.getId());
|
||||
String resBody = execute(new Request.Builder().get().url(path));
|
||||
RoomAliasLookupJson lookup = GsonUtil.get().fromJson(resBody, RoomAliasLookupJson.class);
|
||||
return new RoomAliasLookup(lookup.getRoomId(), alias.getId(), lookup.getServers());
|
||||
}
|
||||
|
||||
@Override
|
||||
public _MatrixRoom createRoom(_RoomCreationOptions options) {
|
||||
URL path = getClientPath("createRoom");
|
||||
String resBody = executeAuthenticated(
|
||||
new Request.Builder().post(getJsonBody(new RoomCreationRequestJson(options))).url(path));
|
||||
String roomId = GsonUtil.get().fromJson(resBody, RoomCreationResponseJson.class).getRoomId();
|
||||
return getRoom(roomId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public _MatrixRoom getRoom(String roomId) {
|
||||
return new MatrixHttpRoom(getContext(), roomId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<_MatrixRoom> getJoinedRooms() {
|
||||
URL path = getClientPath("joined_rooms");
|
||||
JsonObject resBody = GsonUtil.parseObj(executeAuthenticated(new Request.Builder().get().url(path)));
|
||||
return GsonUtil.asList(resBody, "joined_rooms", String.class).stream().map(this::getRoom)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public _MatrixRoom joinRoom(String roomIdOrAlias) {
|
||||
URL path = getClientPath("join", roomIdOrAlias);
|
||||
String resBody = executeAuthenticated(new Request.Builder().post(getJsonBody(new JsonObject())).url(path));
|
||||
String roomId = GsonUtil.get().fromJson(resBody, RoomCreationResponseJson.class).getRoomId();
|
||||
return getRoom(roomId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public _MatrixUser getUser(_MatrixID mxId) {
|
||||
return new MatrixHttpUser(getContext(), mxId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> getDeviceId() {
|
||||
return Optional.ofNullable(context.getDeviceId());
|
||||
}
|
||||
|
||||
protected void updateContext(String resBody) {
|
||||
LoginResponse response = gson.fromJson(resBody, LoginResponse.class);
|
||||
context.setToken(response.getAccessToken());
|
||||
context.setDeviceId(response.getDeviceId());
|
||||
context.setUser(MatrixID.asAcceptable(response.getUserId()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(MatrixPasswordCredentials credentials, String sharedSecret, boolean admin) {
|
||||
// As per synapse registration script:
|
||||
// https://github.com/matrix-org/synapse/blob/master/scripts/register_new_matrix_user#L28
|
||||
|
||||
String value = credentials.getLocalPart() + "\0" + credentials.getPassword() + "\0"
|
||||
+ (admin ? "admin" : "notadmin");
|
||||
String mac = new HmacUtils(HmacAlgorithms.HMAC_SHA_1, sharedSecret).hmacHex(value);
|
||||
JsonObject body = new JsonObject();
|
||||
body.addProperty("user", credentials.getLocalPart());
|
||||
body.addProperty("password", credentials.getPassword());
|
||||
body.addProperty("mac", mac);
|
||||
body.addProperty("type", "org.matrix.login.shared_secret");
|
||||
body.addProperty("admin", false);
|
||||
URL url = getPath("client", "api", "v1", "register");
|
||||
updateContext(execute(new Request.Builder().post(getJsonBody(body)).url(url)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAccessToken(String accessToken) {
|
||||
context.setUser(getIdentity(accessToken));
|
||||
context.setToken(accessToken);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void login(MatrixPasswordCredentials credentials) {
|
||||
URL url = getClientPath("login");
|
||||
|
||||
LoginPostBody data = new LoginPostBody(credentials.getLocalPart(), credentials.getPassword());
|
||||
getDeviceId().ifPresent(data::setDeviceId);
|
||||
Optional.ofNullable(context.getInitialDeviceName()).ifPresent(data::setInitialDeviceDisplayName);
|
||||
|
||||
updateContext(execute(new Request.Builder().post(getJsonBody(data)).url(url)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logout() {
|
||||
URL path = getClientPath("logout");
|
||||
executeAuthenticated(new Request.Builder().post(getJsonBody(new JsonObject())).url(path));
|
||||
context.setToken(null);
|
||||
context.setUser(null);
|
||||
context.setDeviceId(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public _SyncData sync(_SyncOptions options) {
|
||||
long start = System.currentTimeMillis();
|
||||
HttpUrl.Builder path = getClientPathBuilder("sync");
|
||||
path.addQueryParameter("timeout", options.getTimeout().map(Long::intValue).orElse(30000).toString());
|
||||
options.getSince().ifPresent(since -> path.addQueryParameter("since", since));
|
||||
options.getFilter().ifPresent(filter -> path.addQueryParameter("filter", filter));
|
||||
options.withFullState().ifPresent(state -> path.addQueryParameter("full_state", state ? "true" : "false"));
|
||||
options.getSetPresence().ifPresent(presence -> path.addQueryParameter("presence", presence));
|
||||
|
||||
String body = executeAuthenticated(new Request.Builder().get().url(path.build().url()));
|
||||
long request = System.currentTimeMillis();
|
||||
log.info("Sync: network request took {} ms", (request - start));
|
||||
SyncDataJson data = new SyncDataJson(GsonUtil.parseObj(body));
|
||||
long parsing = System.currentTimeMillis();
|
||||
log.info("Sync: parsing took {} ms", (parsing - request));
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public _MatrixContent getMedia(String mxUri) throws IllegalArgumentException {
|
||||
return getMedia(URI.create(mxUri));
|
||||
}
|
||||
|
||||
@Override
|
||||
public _MatrixContent getMedia(URI mxUri) throws IllegalArgumentException {
|
||||
return new MatrixHttpContent(context, mxUri);
|
||||
}
|
||||
|
||||
private String putMedia(Request.Builder builder, String filename) {
|
||||
HttpUrl.Builder b = getMediaPathBuilder("upload");
|
||||
if (StringUtils.isNotEmpty(filename)) b.addQueryParameter("filename", filename);
|
||||
|
||||
String body = executeAuthenticated(builder.url(b.build()));
|
||||
return GsonUtil.getStringOrThrow(GsonUtil.parseObj(body), "content_uri");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String putMedia(byte[] data, String type) {
|
||||
return putMedia(data, type, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String putMedia(byte[] data, String type, String filename) {
|
||||
return putMedia(new Request.Builder().post(RequestBody.create(MediaType.parse(type), data)), filename);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String putMedia(File data, String type) {
|
||||
return putMedia(data, type, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String putMedia(File data, String type, String filename) {
|
||||
return putMedia(new Request.Builder().post(RequestBody.create(MediaType.parse(type), data)), filename);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<JsonObject> getPushers() {
|
||||
URL url = getClientPath("pushers");
|
||||
JsonObject response = GsonUtil.parseObj(executeAuthenticated(new Request.Builder().get().url(url)));
|
||||
return GsonUtil.findArray(response, "pushers").map(array -> GsonUtil.asList(array, JsonObject.class))
|
||||
.orElse(Collections.emptyList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPusher(JsonObject pusher) {
|
||||
URL url = getClientPath("pushers", "set");
|
||||
executeAuthenticated(new Request.Builder().url(url).post(getJsonBody(pusher)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deletePusher(String pushKey) {
|
||||
JsonObject pusher = new JsonObject();
|
||||
pusher.add("kind", JsonNull.INSTANCE);
|
||||
pusher.addProperty("pushkey", pushKey);
|
||||
setPusher(pusher);
|
||||
}
|
||||
|
||||
@Override
|
||||
public _GlobalPushRulesSet getPushRules() {
|
||||
URL url = getClientPath("pushrules", "global", "");
|
||||
JsonObject response = GsonUtil.parseObj(executeAuthenticated(new Request.Builder().url(url).get()));
|
||||
return new GlobalPushRulesSet(response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public _PushRule getPushRule(String scope, String kind, String id) {
|
||||
return new MatrixHttpPushRule(context, scope, kind, id);
|
||||
}
|
||||
|
||||
}
|
48
src/main/java/io/kamax/matrix/client/regular/Presence.java
Normal file
48
src/main/java/io/kamax/matrix/client/regular/Presence.java
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* matrix-java-sdk - Matrix Client SDK for Java
|
||||
* Copyright (C) 2018 Kamax Sàrl
|
||||
*
|
||||
* https://www.kamax.io/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.kamax.matrix.client.regular;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import io.kamax.matrix.client._Presence;
|
||||
import io.kamax.matrix.json.GsonUtil;
|
||||
|
||||
public class Presence implements _Presence {
|
||||
|
||||
private String status;
|
||||
private Long lastActive;
|
||||
|
||||
public Presence(JsonObject json) {
|
||||
this.status = GsonUtil.getStringOrThrow(json, "presence");
|
||||
this.lastActive = GsonUtil.getLong(json, "last_active_ago");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getLastActive() {
|
||||
return lastActive;
|
||||
}
|
||||
|
||||
}
|
390
src/main/java/io/kamax/matrix/client/regular/SyncDataJson.java
Normal file
390
src/main/java/io/kamax/matrix/client/regular/SyncDataJson.java
Normal file
@@ -0,0 +1,390 @@
|
||||
/*
|
||||
* matrix-java-sdk - Matrix Client SDK for Java
|
||||
* Copyright (C) 2018 Kamax Sarl
|
||||
*
|
||||
* https://www.kamax.io/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.kamax.matrix.client.regular;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import io.kamax.matrix.MatrixID;
|
||||
import io.kamax.matrix._MatrixID;
|
||||
import io.kamax.matrix.client._SyncData;
|
||||
import io.kamax.matrix.event.EventKey;
|
||||
import io.kamax.matrix.event._MatrixAccountDataEvent;
|
||||
import io.kamax.matrix.event._MatrixEphemeralEvent;
|
||||
import io.kamax.matrix.event._MatrixPersistentEvent;
|
||||
import io.kamax.matrix.event._MatrixStateEvent;
|
||||
import io.kamax.matrix.json.MatrixJsonObject;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class SyncDataJson extends MatrixJsonObject implements _SyncData {
|
||||
|
||||
public class MatrixPersistentEventJson extends MatrixJsonObject implements _MatrixPersistentEvent {
|
||||
|
||||
public MatrixPersistentEventJson(JsonObject obj) {
|
||||
super(obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return findString(EventKey.Id.get()).orElse(""); // FIXME refactor event structure
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return getString(EventKey.Type.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getTime() {
|
||||
return getLong(EventKey.Timestamp.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public _MatrixID getSender() {
|
||||
return MatrixID.from(getString(EventKey.Sender.get())).acceptable();
|
||||
}
|
||||
}
|
||||
|
||||
public class MatrixEphemeralEventJson extends MatrixJsonObject implements _MatrixEphemeralEvent {
|
||||
|
||||
public MatrixEphemeralEventJson(JsonObject obj) {
|
||||
super(obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return getString(EventKey.Type.get());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class MatrixAccountDataEventJson extends MatrixJsonObject implements _MatrixAccountDataEvent {
|
||||
|
||||
public MatrixAccountDataEventJson(JsonObject obj) {
|
||||
super(obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return getString(EventKey.Type.get());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class MatrixStateEventJson extends MatrixPersistentEventJson implements _MatrixStateEvent {
|
||||
|
||||
public MatrixStateEventJson(JsonObject obj) {
|
||||
super(obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStateKey() {
|
||||
return getString(EventKey.StateKey.get());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class StateJson extends MatrixJsonObject implements _SyncData.State {
|
||||
|
||||
private List<_MatrixStateEvent> events = new ArrayList<>();
|
||||
|
||||
public StateJson(JsonObject obj) {
|
||||
super(obj);
|
||||
|
||||
findArray("events").ifPresent(array -> {
|
||||
for (JsonElement el : array) {
|
||||
events.add(new MatrixStateEventJson(asObj(el)));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<_MatrixStateEvent> getEvents() {
|
||||
return events;
|
||||
}
|
||||
}
|
||||
|
||||
public class TimelineJson extends MatrixJsonObject implements _SyncData.Timeline {
|
||||
|
||||
private List<_MatrixPersistentEvent> events = new ArrayList<>();
|
||||
|
||||
public TimelineJson(JsonObject obj) {
|
||||
super(obj);
|
||||
|
||||
findArray("events").ifPresent(array -> {
|
||||
for (JsonElement el : array) {
|
||||
events.add(new MatrixPersistentEventJson(asObj(el)));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<_MatrixPersistentEvent> getEvents() {
|
||||
return events;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLimited() {
|
||||
return findString("limited").map("true"::equals).orElse(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreviousBatchToken() {
|
||||
return getString("prev_batch");
|
||||
}
|
||||
}
|
||||
|
||||
public class EphemeralJson extends MatrixJsonObject implements _SyncData.Ephemeral {
|
||||
|
||||
private List<_MatrixEphemeralEvent> events = new ArrayList<>();
|
||||
|
||||
public EphemeralJson(JsonObject obj) {
|
||||
super(obj);
|
||||
|
||||
findArray("events").ifPresent(array -> {
|
||||
for (JsonElement el : array) {
|
||||
events.add(new MatrixEphemeralEventJson(asObj(el)));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<_MatrixEphemeralEvent> getEvents() {
|
||||
return events;
|
||||
}
|
||||
}
|
||||
|
||||
public class AccountDataJson extends MatrixJsonObject implements _SyncData.AccountData {
|
||||
|
||||
private List<_MatrixAccountDataEvent> events = new ArrayList<>();
|
||||
|
||||
public AccountDataJson(JsonObject obj) {
|
||||
super(obj);
|
||||
|
||||
findArray("events").ifPresent(array -> {
|
||||
for (JsonElement el : array) {
|
||||
events.add(new MatrixAccountDataEventJson(asObj(el)));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<_MatrixAccountDataEvent> getEvents() {
|
||||
return events;
|
||||
}
|
||||
}
|
||||
|
||||
public class InvitedRoomJson extends MatrixJsonObject implements _SyncData.InvitedRoom {
|
||||
|
||||
private String id;
|
||||
private State state;
|
||||
|
||||
public InvitedRoomJson(String id, JsonObject data) {
|
||||
super(data);
|
||||
this.id = id;
|
||||
this.state = new StateJson(findObj("invite_state").orElseGet(JsonObject::new));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public State getState() {
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
public class UnreadNotificationsJson extends MatrixJsonObject implements _SyncData.UnreadNotifications {
|
||||
|
||||
private long highlights;
|
||||
private long global;
|
||||
|
||||
public UnreadNotificationsJson(JsonObject data) {
|
||||
super(data);
|
||||
this.highlights = findLong("highlight_count").orElse(0L);
|
||||
this.global = findLong("notification_count").orElse(0L);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getHighlightCount() {
|
||||
return highlights;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getNotificationCount() {
|
||||
return global;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class JoinedRoomJson extends MatrixJsonObject implements _SyncData.JoinedRoom {
|
||||
|
||||
private String id;
|
||||
private State state;
|
||||
private Timeline timeline;
|
||||
private UnreadNotifications unreadNotifications;
|
||||
private Ephemeral ephemeral;
|
||||
private AccountData accountData;
|
||||
|
||||
public JoinedRoomJson(String id, JsonObject data) {
|
||||
super(data);
|
||||
this.id = id;
|
||||
this.state = new StateJson(findObj("state").orElseGet(JsonObject::new));
|
||||
this.timeline = new TimelineJson(findObj("timeline").orElseGet(JsonObject::new));
|
||||
this.unreadNotifications = new UnreadNotificationsJson(computeObj("unread_notifications"));
|
||||
this.ephemeral = new EphemeralJson(findObj("ephemeral").orElseGet(JsonObject::new));
|
||||
this.accountData = new AccountDataJson(findObj("account_data").orElseGet(JsonObject::new));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public State getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Timeline getTimeline() {
|
||||
return timeline;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Ephemeral getEphemeral() {
|
||||
return ephemeral;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccountData getAccountData() {
|
||||
return accountData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UnreadNotifications getUnreadNotifications() {
|
||||
return unreadNotifications;
|
||||
}
|
||||
}
|
||||
|
||||
public class LeftRoomJson extends MatrixPersistentEventJson implements _SyncData.LeftRoom {
|
||||
|
||||
private String id;
|
||||
private State state;
|
||||
private Timeline timeline;
|
||||
|
||||
public LeftRoomJson(String id, JsonObject data) {
|
||||
super(data);
|
||||
this.id = id;
|
||||
this.state = new StateJson(findObj("state").orElseGet(JsonObject::new));
|
||||
this.timeline = new TimelineJson(findObj("timeline").orElseGet(JsonObject::new));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public State getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Timeline getTimeline() {
|
||||
return timeline;
|
||||
}
|
||||
}
|
||||
|
||||
public class RoomsJson extends MatrixJsonObject implements _SyncData.Rooms {
|
||||
|
||||
private Set<InvitedRoom> invited = new HashSet<>();
|
||||
private Set<JoinedRoom> joined = new HashSet<>();
|
||||
private Set<LeftRoom> left = new HashSet<>();
|
||||
|
||||
public RoomsJson(JsonObject obj) {
|
||||
super(obj);
|
||||
findObj("invite").ifPresent(o -> {
|
||||
for (Map.Entry<String, JsonElement> entry : o.entrySet()) {
|
||||
invited.add(new InvitedRoomJson(entry.getKey(), asObj(entry.getValue())));
|
||||
}
|
||||
});
|
||||
|
||||
findObj("join").ifPresent(o -> {
|
||||
for (Map.Entry<String, JsonElement> entry : o.entrySet()) {
|
||||
joined.add(new JoinedRoomJson(entry.getKey(), asObj(entry.getValue())));
|
||||
}
|
||||
});
|
||||
|
||||
findObj("leave").ifPresent(o -> {
|
||||
for (Map.Entry<String, JsonElement> entry : o.entrySet()) {
|
||||
left.add(new LeftRoomJson(entry.getKey(), asObj(entry.getValue())));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<InvitedRoom> getInvited() {
|
||||
return invited;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<JoinedRoom> getJoined() {
|
||||
return joined;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<LeftRoom> getLeft() {
|
||||
return left;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private String nextBatch;
|
||||
private AccountDataJson accountData;
|
||||
private RoomsJson rooms;
|
||||
|
||||
public SyncDataJson(JsonObject data) {
|
||||
super(data);
|
||||
nextBatch = getString("next_batch");
|
||||
accountData = new AccountDataJson(findObj("account_data").orElseGet(JsonObject::new));
|
||||
rooms = new RoomsJson(findObj("rooms").orElseGet(JsonObject::new));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String nextBatchToken() {
|
||||
return nextBatch;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccountData getAccountData() {
|
||||
return accountData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Rooms getRooms() {
|
||||
return rooms;
|
||||
}
|
||||
|
||||
}
|
103
src/main/java/io/kamax/matrix/client/regular/SyncOptions.java
Normal file
103
src/main/java/io/kamax/matrix/client/regular/SyncOptions.java
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* matrix-java-sdk - Matrix Client SDK for Java
|
||||
* Copyright (C) 2018 Kamax Sarl
|
||||
*
|
||||
* https://www.kamax.io/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.kamax.matrix.client.regular;
|
||||
|
||||
import io.kamax.matrix.client._SyncOptions;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public class SyncOptions implements _SyncOptions {
|
||||
|
||||
public static class Builder {
|
||||
|
||||
private final SyncOptions obj;
|
||||
|
||||
public Builder() {
|
||||
this.obj = new SyncOptions();
|
||||
}
|
||||
|
||||
public SyncOptions get() {
|
||||
return obj;
|
||||
}
|
||||
|
||||
public Builder setSince(String since) {
|
||||
obj.since = since;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setFilter(String filter) {
|
||||
obj.filter = filter;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setWithFullState(boolean withFullState) {
|
||||
obj.fullState = withFullState;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setPresence(boolean setPresence) {
|
||||
obj.setPresence = setPresence ? null : "offline";
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setTimeout(long timeout) {
|
||||
obj.timeout = timeout;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static Builder build() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
private String since;
|
||||
private String filter;
|
||||
private Boolean fullState;
|
||||
private String setPresence;
|
||||
private Long timeout;
|
||||
|
||||
@Override
|
||||
public Optional<String> getSince() {
|
||||
return Optional.ofNullable(since);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> getFilter() {
|
||||
return Optional.ofNullable(filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Boolean> withFullState() {
|
||||
return Optional.ofNullable(fullState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> getSetPresence() {
|
||||
return Optional.ofNullable(setPresence);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Long> getTimeout() {
|
||||
return Optional.ofNullable(timeout);
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user