Code cleanup

This commit is contained in:
Andrea Cavalli 2021-10-22 12:54:28 +02:00
parent cb024a114f
commit e0f70138c1
52 changed files with 306 additions and 291 deletions

View File

@ -20,6 +20,7 @@
**Operating systems**: Linux, Windows, MacOS
**CPU architectures**:
- i386/x86 (Linux, Windows)
- amd64/x86_64 (Linux, Windows, OSX)
- armhf/armv7 (Linux)
@ -30,7 +31,9 @@
**Required libraries for Linux: OpenSSL and zlib**
### Install OpenSSL on macOS
You must install `openssl@1.1` using the <a href="https://brew.sh">brew package manager </a>, then link openssl to `/usr/local/opt/openssl`
You must install `openssl@1.1` using the <a href="https://brew.sh">brew package manager </a>, then link openssl
to `/usr/local/opt/openssl`
If you don't know how to do this, type the following commands in your terminal:
@ -40,9 +43,13 @@ ln -sf /usr/local/Cellar/openssl@1.1/1.1.1l /usr/local/opt/openssl
```
## 📚 How to use the library
### Setting up the library using Maven
If you are using Maven, edit your `pom.xml` file as below:
```xml
<project>
<repositories>
@ -73,13 +80,17 @@ If you are using Maven, edit your `pom.xml` file as below:
</dependencies>
</project>
```
Replace `VERSION` with the latest release version, you can find it [here](https://github.com/tdlight-team/tdlight-java/releases).
Replace `NATIVES_VERSION` with the latest native version.
Make sure that you are using the correct natives version for the release that you are using.
Replace `VERSION` with the latest release version, you can find
it [here](https://github.com/tdlight-team/tdlight-java/releases).
Replace `NATIVES_VERSION` with the latest native version. Make sure that you are using the correct natives version for
the release that you are using.
## Setting up the library using Gradle
If you are using Gradle, add the following lines into your `build.gradle` file
```groovy
repositories {
maven { url "https://mvn.mchv.eu/repository/mchv/" }
@ -90,13 +101,17 @@ dependencies {
// Include other native versions that you want, for example for windows, osx, ...
}
```
Replace `VERSION` with the latest release version, you can find it [here](https://github.com/tdlight-team/tdlight-java/releases).
Replace `NATIVES_VERSION` with the latest native version.
Make sure that you are using the correct natives version for the release that you are using.
Replace `VERSION` with the latest release version, you can find
it [here](https://github.com/tdlight-team/tdlight-java/releases).
Replace `NATIVES_VERSION` with the latest native version. Make sure that you are using the correct natives version for
the release that you are using.
## ⚒ Native dependencies
To use TDLight Java you need to include one or more native dependencies:
- `tdlight-natives-linux-amd64`
- `tdlight-natives-linux-aarch64`
- `tdlight-natives-linux-x86`
@ -107,26 +122,37 @@ To use TDLight Java you need to include one or more native dependencies:
- `tdlight-natives-osx-amd64`
## Usage
An example on how to use TDLight Java can be found here: [Example.java](https://github.com/tdlight-team/tdlight-java/blob/master/example/src/main/java/it.tdlight.example/Example.java)
An example on how to use TDLight Java can be found
here: [Example.java](https://github.com/tdlight-team/tdlight-java/blob/master/example/src/main/java/it.tdlight.example/Example.java)
### Advanced usage
If you want to disable the automatic runtime shutdown hook, you should set the property `it.tdlight.enableShutdownHooks` to `false`
If you want to disable the automatic runtime shutdown hook, you should set the property `it.tdlight.enableShutdownHooks`
to `false`
### TDLight methods documentation
[TdApi JavaDoc](https://tdlight-team.github.io/tdlight-docs)
### TDLight extended features
TDLight has some extended features compared to TDLib, that you can see on the [TDLight official repository](https://github.com/tdlight-team/tdlight#tdlight-extra-features).
TDLight has some extended features compared to TDLib, that you can see on
the [TDLight official repository](https://github.com/tdlight-team/tdlight#tdlight-extra-features).
## About
### **License**
TDLight is licensed by Andrea Cavalli <andrea@cavallium.it> under the terms of the GNU Lesser General Public License 3
### **Libraries licenses**
JTDLib is licensed by Ernesto Castellotti <erny.castell@gmail.com> under the terms of the GNU Lesser General Public License 3
JTDLib is licensed by Ernesto Castellotti <erny.castell@gmail.com> under the terms of the GNU Lesser General Public
License 3
TDLib is licensed by Aliaksei Levin <levlam@telegram.org> and Arseny Smirnov <arseny30@gmail.com> under the terms of the Boost Software License
TDLib is licensed by Aliaksei Levin <levlam@telegram.org> and Arseny Smirnov <arseny30@gmail.com> under the terms of the
Boost Software License
OpenSSL is licensed under the terms of Apache License v2

View File

@ -1,16 +1,16 @@
package it.tdlight.example;
import it.tdlight.common.TelegramClient;
import it.tdlight.tdlight.ClientManager;
import it.tdlight.common.Init;
import it.tdlight.common.TelegramClient;
import it.tdlight.common.utils.CantLoadLibrary;
import it.tdlight.jni.TdApi;
import it.tdlight.tdlight.ClientManager;
/**
* This is an advanced example that uses directly the native client without using the SimpleClient implementation
*/
public class AdvancedExample {
public static void main(String[] args) throws CantLoadLibrary {
// Initialize TDLight native libraries
Init.start();

View File

@ -1,16 +1,11 @@
package it.tdlight.example;
import it.tdlight.client.APIToken;
import it.tdlight.client.Authenticable;
import it.tdlight.client.AuthenticationData;
import it.tdlight.client.CommandHandler;
import it.tdlight.client.Result;
import it.tdlight.client.SimpleTelegramClient;
import it.tdlight.client.TDLibSettings;
import it.tdlight.common.ExceptionHandler;
import it.tdlight.common.Init;
import it.tdlight.common.ResultHandler;
import it.tdlight.common.TelegramClient;
import it.tdlight.common.utils.CantLoadLibrary;
import it.tdlight.jni.TdApi;
import it.tdlight.jni.TdApi.AuthorizationState;
@ -21,24 +16,11 @@ import it.tdlight.jni.TdApi.MessageSenderUser;
import it.tdlight.jni.TdApi.MessageText;
import it.tdlight.jni.TdApi.UpdateAuthorizationState;
import it.tdlight.jni.TdApi.UpdateNewMessage;
import it.tdlight.tdlight.ClientManager;
import java.io.BufferedReader;
import java.io.IOError;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.NavigableSet;
import java.util.TreeSet;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* Example class for TDLight Java
*
* The documentation of the TDLight functions can be found here:
* https://tdlight-team.github.io/tdlight-docs
* <p>
* The documentation of the TDLight functions can be found here: https://tdlight-team.github.io/tdlight-docs
*/
public final class Example {

View File

@ -1,5 +1,7 @@
package it.tdlight.common.utils;
public final class LibraryVersion {
public static final String VERSION = "${project.version}";
public static final String NATIVES_VERSION = "4.0.${nativesRevisionNumber}${nativesRevisionSuffix}";
public static final String IMPLEMENTATION_NAME = "tdlib";

View File

@ -1,5 +1,7 @@
package it.tdlight.common.utils;
public final class LibraryVersion {
public static final String VERSION = "${project.version}";
public static final String NATIVES_VERSION = "4.0.${nativesRevisionNumber}${nativesRevisionSuffix}";
public static final String IMPLEMENTATION_NAME = "tdlight";

View File

@ -4,6 +4,7 @@ import java.util.Objects;
@SuppressWarnings("unused")
final class AuthenticationDataImpl implements AuthenticationData {
private final Long userPhoneNumber;
private final String botToken;

View File

@ -1,9 +1,7 @@
package it.tdlight.client;
import it.tdlight.common.TelegramClient;
import it.tdlight.jni.TdApi;
import it.tdlight.jni.TdApi.AuthorizationStateReady;
import it.tdlight.jni.TdApi.Error;
import it.tdlight.jni.TdApi.GetMe;
import it.tdlight.jni.TdApi.UpdateAuthorizationState;
import it.tdlight.jni.TdApi.User;

View File

@ -2,17 +2,11 @@ package it.tdlight.client;
import it.tdlight.common.ExceptionHandler;
import it.tdlight.common.TelegramClient;
import it.tdlight.common.utils.ScannerUtils;
import it.tdlight.jni.TdApi;
import it.tdlight.jni.TdApi.AuthorizationStateWaitEncryptionKey;
import it.tdlight.jni.TdApi.AuthorizationStateWaitPhoneNumber;
import it.tdlight.jni.TdApi.CheckDatabaseEncryptionKey;
import it.tdlight.jni.TdApi.Error;
import it.tdlight.jni.TdApi.PhoneNumberAuthenticationSettings;
import it.tdlight.jni.TdApi.SetAuthenticationPhoneNumber;
import it.tdlight.jni.TdApi.UpdateAuthorizationState;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
final class AuthorizationStateWaitAuthenticationDataHandler implements GenericUpdateHandler<UpdateAuthorizationState> {

View File

@ -2,15 +2,9 @@ package it.tdlight.client;
import it.tdlight.common.ExceptionHandler;
import it.tdlight.common.TelegramClient;
import it.tdlight.jni.TdApi;
import it.tdlight.jni.TdApi.AuthorizationStateWaitCode;
import it.tdlight.jni.TdApi.AuthorizationStateWaitOtherDeviceConfirmation;
import it.tdlight.jni.TdApi.CheckAuthenticationCode;
import it.tdlight.jni.TdApi.Error;
import it.tdlight.jni.TdApi.Function;
import it.tdlight.jni.TdApi.UpdateAuthorizationState;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
final class AuthorizationStateWaitCodeHandler implements GenericUpdateHandler<UpdateAuthorizationState> {
@ -29,8 +23,7 @@ final class AuthorizationStateWaitCodeHandler implements GenericUpdateHandler<Up
@Override
public void onUpdate(UpdateAuthorizationState update) {
if (update.authorizationState.getConstructor() == AuthorizationStateWaitCode.CONSTRUCTOR) {
AuthorizationStateWaitCode authorizationState =
(AuthorizationStateWaitCode) update.authorizationState;
AuthorizationStateWaitCode authorizationState = (AuthorizationStateWaitCode) update.authorizationState;
ParameterInfo parameterInfo = new ParameterInfoCode(authorizationState.codeInfo.phoneNumber,
authorizationState.codeInfo.nextType,
authorizationState.codeInfo.timeout,

View File

@ -3,14 +3,8 @@ package it.tdlight.client;
import it.tdlight.common.ExceptionHandler;
import it.tdlight.common.TelegramClient;
import it.tdlight.jni.TdApi.AuthorizationStateWaitEncryptionKey;
import it.tdlight.jni.TdApi.AuthorizationStateWaitTdlibParameters;
import it.tdlight.jni.TdApi.CheckDatabaseEncryptionKey;
import it.tdlight.jni.TdApi.Error;
import it.tdlight.jni.TdApi.SetTdlibParameters;
import it.tdlight.jni.TdApi.TdlibParameters;
import it.tdlight.jni.TdApi.UpdateAuthorizationState;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
final class AuthorizationStateWaitEncryptionKeyHandler implements GenericUpdateHandler<UpdateAuthorizationState> {

View File

@ -1,6 +1,5 @@
package it.tdlight.client;
import it.tdlight.common.TelegramClient;
import it.tdlight.jni.TdApi;
import it.tdlight.jni.TdApi.AuthorizationStateClosed;
import it.tdlight.jni.TdApi.UpdateAuthorizationState;

View File

@ -1,12 +1,10 @@
package it.tdlight.client;
import it.tdlight.common.ExceptionHandler;
import it.tdlight.common.TelegramClient;
import it.tdlight.jni.TdApi.AuthorizationStateWaitOtherDeviceConfirmation;
import it.tdlight.jni.TdApi.UpdateAuthorizationState;
final class AuthorizationStateWaitOtherDeviceConfirmationHandler
implements GenericUpdateHandler<UpdateAuthorizationState> {
final class AuthorizationStateWaitOtherDeviceConfirmationHandler implements
GenericUpdateHandler<UpdateAuthorizationState> {
private final ClientInteraction clientInteraction;
@ -17,8 +15,7 @@ final class AuthorizationStateWaitOtherDeviceConfirmationHandler
@Override
public void onUpdate(UpdateAuthorizationState update) {
if (update.authorizationState.getConstructor() == AuthorizationStateWaitOtherDeviceConfirmation.CONSTRUCTOR) {
AuthorizationStateWaitOtherDeviceConfirmation authorizationState =
(AuthorizationStateWaitOtherDeviceConfirmation) update.authorizationState;
AuthorizationStateWaitOtherDeviceConfirmation authorizationState = (AuthorizationStateWaitOtherDeviceConfirmation) update.authorizationState;
ParameterInfo parameterInfo = new ParameterInfoNotifyLink(authorizationState.link);
clientInteraction.onParameterRequest(InputParameter.NOTIFY_LINK, parameterInfo);
}

View File

@ -2,15 +2,9 @@ package it.tdlight.client;
import it.tdlight.common.ExceptionHandler;
import it.tdlight.common.TelegramClient;
import it.tdlight.jni.TdApi.AuthorizationStateWaitCode;
import it.tdlight.jni.TdApi.AuthorizationStateWaitPassword;
import it.tdlight.jni.TdApi.CheckAuthenticationCode;
import it.tdlight.jni.TdApi.CheckAuthenticationPassword;
import it.tdlight.jni.TdApi.Error;
import it.tdlight.jni.TdApi.Function;
import it.tdlight.jni.TdApi.UpdateAuthorizationState;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
final class AuthorizationStateWaitPasswordHandler implements GenericUpdateHandler<UpdateAuthorizationState> {
@ -29,8 +23,7 @@ final class AuthorizationStateWaitPasswordHandler implements GenericUpdateHandle
@Override
public void onUpdate(UpdateAuthorizationState update) {
if (update.authorizationState.getConstructor() == AuthorizationStateWaitPassword.CONSTRUCTOR) {
AuthorizationStateWaitPassword authorizationState =
(AuthorizationStateWaitPassword) update.authorizationState;
AuthorizationStateWaitPassword authorizationState = (AuthorizationStateWaitPassword) update.authorizationState;
ParameterInfo parameterInfo = new ParameterInfoPasswordHint(authorizationState.passwordHint,
authorizationState.hasRecoveryEmailAddress,
authorizationState.recoveryEmailAddressPattern

View File

@ -4,11 +4,8 @@ import it.tdlight.common.ExceptionHandler;
import it.tdlight.common.TelegramClient;
import it.tdlight.jni.TdApi;
import it.tdlight.jni.TdApi.AuthorizationStateWaitRegistration;
import it.tdlight.jni.TdApi.Error;
import it.tdlight.jni.TdApi.RegisterUser;
import it.tdlight.jni.TdApi.UpdateAuthorizationState;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
final class AuthorizationStateWaitRegistrationHandler implements GenericUpdateHandler<UpdateAuthorizationState> {
@ -27,9 +24,10 @@ final class AuthorizationStateWaitRegistrationHandler implements GenericUpdateHa
@Override
public void onUpdate(UpdateAuthorizationState update) {
if (update.authorizationState.getConstructor() == AuthorizationStateWaitRegistration.CONSTRUCTOR) {
TdApi.AuthorizationStateWaitRegistration authorizationState =
(TdApi.AuthorizationStateWaitRegistration) update.authorizationState;
clientInteraction.onParameterRequest(InputParameter.TERMS_OF_SERVICE, new ParameterInfoTermsOfService(authorizationState.termsOfService));
TdApi.AuthorizationStateWaitRegistration authorizationState = (TdApi.AuthorizationStateWaitRegistration) update.authorizationState;
clientInteraction.onParameterRequest(InputParameter.TERMS_OF_SERVICE,
new ParameterInfoTermsOfService(authorizationState.termsOfService)
);
String firstName = clientInteraction.onParameterRequest(InputParameter.ASK_FIRST_NAME, new EmptyParameterInfo());
String lastName = clientInteraction.onParameterRequest(InputParameter.ASK_LAST_NAME, new EmptyParameterInfo());
if (firstName == null || firstName.isEmpty()) {

View File

@ -3,12 +3,9 @@ package it.tdlight.client;
import it.tdlight.common.ExceptionHandler;
import it.tdlight.common.TelegramClient;
import it.tdlight.jni.TdApi.AuthorizationStateWaitTdlibParameters;
import it.tdlight.jni.TdApi.Error;
import it.tdlight.jni.TdApi.SetTdlibParameters;
import it.tdlight.jni.TdApi.TdlibParameters;
import it.tdlight.jni.TdApi.UpdateAuthorizationState;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
final class AuthorizationStateWaitTdlibParametersHandler implements GenericUpdateHandler<UpdateAuthorizationState> {

View File

@ -2,7 +2,6 @@ package it.tdlight.client;
import it.tdlight.jni.TdApi;
import it.tdlight.jni.TdApi.Chat;
import it.tdlight.jni.TdApi.User;
public interface CommandHandler {

View File

@ -3,7 +3,6 @@ package it.tdlight.client;
import it.tdlight.common.TelegramClient;
import it.tdlight.jni.TdApi;
import it.tdlight.jni.TdApi.Chat;
import it.tdlight.jni.TdApi.Error;
import it.tdlight.jni.TdApi.Message;
import it.tdlight.jni.TdApi.MessageText;
import it.tdlight.jni.TdApi.UpdateNewMessage;
@ -36,9 +35,8 @@ final class CommandsHandler implements GenericUpdateHandler<UpdateNewMessage> {
public void onUpdate(UpdateNewMessage update) {
if (update.getConstructor() == UpdateNewMessage.CONSTRUCTOR) {
Message message = update.message;
if (message.forwardInfo == null && !message.isChannelPost
&& (message.authorSignature == null || message.authorSignature.isEmpty())
&& message.content.getConstructor() == MessageText.CONSTRUCTOR) {
if (message.forwardInfo == null && !message.isChannelPost && (message.authorSignature == null
|| message.authorSignature.isEmpty()) && message.content.getConstructor() == MessageText.CONSTRUCTOR) {
MessageText messageText = (MessageText) message.content;
String text = messageText.text.text;
if (text.startsWith("/")) {
@ -71,15 +69,12 @@ final class CommandsHandler implements GenericUpdateHandler<UpdateNewMessage> {
Set<CommandHandler> handlers = commandHandlers.getOrDefault(currentCommandName, Collections.emptySet());
for (CommandHandler handler : handlers) {
client.send(new TdApi.GetChat(message.chatId),
response -> {
client.send(new TdApi.GetChat(message.chatId), response -> {
if (response.getConstructor() == Error.CONSTRUCTOR) {
throw new TelegramError((Error) response);
}
handler.onCommand((Chat) response, message.sender, arguments);
},
error -> logger.warn("Error when handling the command {}", commandName, error)
);
}, error -> logger.warn("Error when handling the command {}", commandName, error));
}
}
}

View File

@ -2,7 +2,6 @@ package it.tdlight.client;
import it.tdlight.common.utils.ScannerUtils;
import java.util.Locale;
import java.util.stream.Collector;
final class ConsoleInteractiveAuthenticationData implements AuthenticationData {
@ -57,10 +56,14 @@ final class ConsoleInteractiveAuthenticationData implements AuthenticationData {
}
private void initializeIfNeeded() {
if (initialized) return;
if (initialized) {
return;
}
synchronized (LOCK) {
if (initialized) return;
if (initialized) {
return;
}
String choice;
@ -68,7 +71,9 @@ final class ConsoleInteractiveAuthenticationData implements AuthenticationData {
String mode;
do {
choice = ScannerUtils
.askParameter("login", "Do you want to login using a bot [token], a [phone] number, or a [qr] code? [token/phone/qr]")
.askParameter("login",
"Do you want to login using a bot [token], a [phone] number, or a [qr] code? [token/phone/qr]"
)
.trim()
.toLowerCase(Locale.ROOT);
switch (choice) {

View File

@ -1,8 +1,6 @@
package it.tdlight.client;
import it.tdlight.jni.TdApi;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Interface for incoming responses from TDLib.

View File

@ -1,6 +1,5 @@
package it.tdlight.client;
import it.tdlight.jni.TdApi.Object;
import it.tdlight.jni.TdApi.Update;
/**

View File

@ -1,10 +1,5 @@
package it.tdlight.client;
public enum InputParameter {
ASK_FIRST_NAME,
ASK_LAST_NAME,
ASK_CODE,
ASK_PASSWORD,
NOTIFY_LINK,
TERMS_OF_SERVICE
ASK_FIRST_NAME, ASK_LAST_NAME, ASK_CODE, ASK_PASSWORD, NOTIFY_LINK, TERMS_OF_SERVICE
}

View File

@ -5,6 +5,7 @@ import java.util.Objects;
import java.util.StringJoiner;
public final class ParameterInfoCode implements ParameterInfo {
private final String phoneNumber;
private final AuthenticationCodeType nextType;
private final int timeout;

View File

@ -5,6 +5,7 @@ import java.util.Objects;
import java.util.StringJoiner;
public final class ParameterInfoTermsOfService implements ParameterInfo {
private final TermsOfService termsOfService;
public ParameterInfoTermsOfService(TermsOfService termsOfService) {

View File

@ -33,16 +33,27 @@ final class ScannerClientInteraction implements ClientInteraction {
String question;
boolean trim = false;
switch (parameter) {
case ASK_FIRST_NAME: question = "Enter first name"; trim = true; break;
case ASK_LAST_NAME: question = "Enter last name"; trim = true; break;
case ASK_FIRST_NAME:
question = "Enter first name";
trim = true;
break;
case ASK_LAST_NAME:
question = "Enter last name";
trim = true;
break;
case ASK_CODE:
question = "Enter authentication code";
ParameterInfoCode codeInfo = ((ParameterInfoCode) parameterInfo);
question += "\n\tPhone number: " + codeInfo.getPhoneNumber();
question += "\n\tTimeout: " + codeInfo.getTimeout() + " seconds";
question += "\n\tCode type: " + codeInfo.getType().getClass().getSimpleName().replace("AuthenticationCodeType", "");
question +=
"\n\tCode type: " + codeInfo.getType().getClass().getSimpleName().replace("AuthenticationCodeType", "");
if (codeInfo.getNextType() != null) {
question += "\n\tNext code type: " + codeInfo.getNextType().getClass().getSimpleName().replace("AuthenticationCodeType", "");
question += "\n\tNext code type: " + codeInfo
.getNextType()
.getClass()
.getSimpleName()
.replace("AuthenticationCodeType", "");
}
trim = true;
break;
@ -82,7 +93,9 @@ final class ScannerClientInteraction implements ClientInteraction {
return "";
}
break;
default: question = parameter.toString(); break;
default:
question = parameter.toString();
break;
}
String result = ScannerUtils.askParameter(who, question);
if (trim) {

View File

@ -10,7 +10,6 @@ import it.tdlight.common.internal.CommonClientManager;
import it.tdlight.common.utils.CantLoadLibrary;
import it.tdlight.common.utils.LibraryVersion;
import it.tdlight.jni.TdApi;
import it.tdlight.jni.TdApi.Error;
import it.tdlight.jni.TdApi.Function;
import it.tdlight.jni.TdApi.User;
import java.io.IOException;
@ -49,13 +48,12 @@ public final class SimpleTelegramClient implements Authenticable {
private AuthenticationData authenticationData;
private final Map<String, Set<CommandHandler>> commandHandlers = new ConcurrentHashMap<>();
private final Set<ResultHandler<TdApi.Update>> updateHandlers
= new ConcurrentHashMap<ResultHandler<TdApi.Update>, Object>()
.keySet(new Object());
private final Set<ExceptionHandler> updateExceptionHandlers = new ConcurrentHashMap<ExceptionHandler, Object>()
.keySet(new Object());
private final Set<ExceptionHandler> defaultExceptionHandlers = new ConcurrentHashMap<ExceptionHandler, Object>()
.keySet(new Object());
private final Set<ResultHandler<TdApi.Update>> updateHandlers = new ConcurrentHashMap<ResultHandler<TdApi.Update>, Object>().keySet(
new Object());
private final Set<ExceptionHandler> updateExceptionHandlers = new ConcurrentHashMap<ExceptionHandler, Object>().keySet(
new Object());
private final Set<ExceptionHandler> defaultExceptionHandlers = new ConcurrentHashMap<ExceptionHandler, Object>().keySet(
new Object());
private final CountDownLatch closed = new CountDownLatch(1);
@ -63,23 +61,35 @@ public final class SimpleTelegramClient implements Authenticable {
this.client = CommonClientManager.create(LibraryVersion.IMPLEMENTATION_NAME);
this.settings = settings;
this.addUpdateHandler(TdApi.UpdateAuthorizationState.class,
new AuthorizationStateWaitTdlibParametersHandler(client, settings, this::handleDefaultException));
new AuthorizationStateWaitTdlibParametersHandler(client, settings, this::handleDefaultException)
);
this.addUpdateHandler(TdApi.UpdateAuthorizationState.class,
new AuthorizationStateWaitEncryptionKeyHandler(client, this::handleDefaultException));
new AuthorizationStateWaitEncryptionKeyHandler(client, this::handleDefaultException)
);
this.addUpdateHandler(TdApi.UpdateAuthorizationState.class,
new AuthorizationStateWaitAuthenticationDataHandler(client, this,
this::handleDefaultException));
new AuthorizationStateWaitAuthenticationDataHandler(client, this, this::handleDefaultException)
);
this.addUpdateHandler(TdApi.UpdateAuthorizationState.class,
new AuthorizationStateWaitRegistrationHandler(client, new SimpleTelegramClientInteraction(),
this::handleDefaultException));
new AuthorizationStateWaitRegistrationHandler(client,
new SimpleTelegramClientInteraction(),
this::handleDefaultException
)
);
this.addUpdateHandler(TdApi.UpdateAuthorizationState.class,
new AuthorizationStateWaitPasswordHandler(client, new SimpleTelegramClientInteraction(),
this::handleDefaultException));
new AuthorizationStateWaitPasswordHandler(client,
new SimpleTelegramClientInteraction(),
this::handleDefaultException
)
);
this.addUpdateHandler(TdApi.UpdateAuthorizationState.class,
new AuthorizationStateWaitOtherDeviceConfirmationHandler(new SimpleTelegramClientInteraction()));
new AuthorizationStateWaitOtherDeviceConfirmationHandler(new SimpleTelegramClientInteraction())
);
this.addUpdateHandler(TdApi.UpdateAuthorizationState.class,
new AuthorizationStateWaitCodeHandler(client, new SimpleTelegramClientInteraction(),
this::handleDefaultException));
new AuthorizationStateWaitCodeHandler(client,
new SimpleTelegramClientInteraction(),
this::handleDefaultException
)
);
this.addUpdateHandler(TdApi.UpdateAuthorizationState.class, new AuthorizationStateWaitForExit(this.closed));
AtomicReference<User> me = new AtomicReference<>();
this.addUpdateHandler(TdApi.UpdateAuthorizationState.class, new AuthorizationStateReadyGetMe(client, me));
@ -133,8 +143,9 @@ public final class SimpleTelegramClient implements Authenticable {
}
public <T extends TdApi.Update> void addCommandHandler(String commandName, CommandHandler handler) {
Set<CommandHandler> handlers = this.commandHandlers
.computeIfAbsent(commandName, k -> new ConcurrentHashMap<CommandHandler, Object>().keySet(new Object()));
Set<CommandHandler> handlers = this.commandHandlers.computeIfAbsent(commandName,
k -> new ConcurrentHashMap<CommandHandler, Object>().keySet(new Object())
);
handlers.add(handler);
}

View File

@ -209,7 +209,8 @@ public final class TDLibSettings {
downloadedFilesDirectoryPath,
fileDatabaseEnabled,
chatInfoDatabaseEnabled,
messageDatabaseEnabled, apiToken,
messageDatabaseEnabled,
apiToken,
systemLanguageCode,
deviceModel,
systemVersion,

View File

@ -3,7 +3,6 @@ package it.tdlight.client;
import it.tdlight.jni.TdApi;
import it.tdlight.jni.TdApi.Error;
import java.util.Objects;
import java.util.StringJoiner;
public final class TelegramError extends RuntimeException {

View File

@ -1,7 +1,5 @@
package it.tdlight.common;
import it.tdlight.jni.TdApi.Object;
public interface ClientEventsHandler {
int getClientId();

View File

@ -1,7 +1,5 @@
package it.tdlight.common;
import it.tdlight.jni.TdApi.Object;
public interface EventsHandler {
void handleClientEvents(int clientId,

View File

@ -19,7 +19,6 @@ package it.tdlight.common;
import it.tdlight.common.utils.CantLoadLibrary;
import it.tdlight.common.utils.LoadLibrary;
import it.tdlight.common.utils.Os;
/**
* Init class to successfully initialize Tdlib

View File

@ -1,7 +1,7 @@
package it.tdlight.common;
import it.tdlight.tdnative.NativeLog;
import it.tdlight.jni.TdApi;
import it.tdlight.tdnative.NativeLog;
import java.util.function.Consumer;
/**

View File

@ -26,11 +26,14 @@ import java.util.StringJoiner;
*/
@SuppressWarnings("unused")
public final class Response {
private final long id;
private final TdApi.Object object;
/**
* Creates a response with eventId and object, do not create answers explicitly! you must receive the reply through a client.
* Creates a response with eventId and object, do not create answers explicitly! you must receive the reply through a
* client.
*
* @param id TDLib request identifier, which corresponds to the response or 0 for incoming updates from TDLib.
* @param object TDLib API object representing a response to a TDLib request or an incoming update.
*/
@ -41,6 +44,7 @@ public final class Response {
/**
* Get TDLib request identifier.
*
* @return TDLib request identifier, which corresponds to the response or 0 for incoming updates from TDLib.
*/
public long getId() {
@ -49,6 +53,7 @@ public final class Response {
/**
* Get TDLib API object.
*
* @return TDLib API object representing a response to a TDLib request or an incoming update.
*/
public TdApi.Object getObject() {

View File

@ -1,7 +1,5 @@
package it.tdlight.common;
public enum SignalType {
UPDATE,
EXCEPTION,
CLOSE
UPDATE, EXCEPTION, CLOSE
}

View File

@ -41,7 +41,8 @@ public interface TelegramClient {
* resultHandler. If it is null, then defaultExceptionHandler will be called.
* @throws NullPointerException if query is null.
*/
<R extends TdApi.Object> void send(TdApi.Function<R> query, ResultHandler<R> resultHandler,
<R extends TdApi.Object> void send(TdApi.Function<R> query,
ResultHandler<R> resultHandler,
ExceptionHandler exceptionHandler);
/**

View File

@ -1,6 +1,5 @@
package it.tdlight.common;
import it.tdlight.jni.TdApi.Object;
import java.util.List;
/**

View File

@ -5,6 +5,7 @@ import it.tdlight.common.ResultHandler;
import it.tdlight.jni.TdApi;
public final class Handler<R extends TdApi.Object> {
private final ResultHandler<R> resultHandler;
private final ExceptionHandler exceptionHandler;

View File

@ -6,7 +6,6 @@ import it.tdlight.common.ResultHandler;
import it.tdlight.common.TelegramClient;
import it.tdlight.common.UpdatesHandler;
import it.tdlight.jni.TdApi;
import it.tdlight.jni.TdApi.Error;
import it.tdlight.jni.TdApi.Function;
import it.unimi.dsi.fastutil.longs.LongArrayList;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
@ -46,8 +45,7 @@ public final class InternalClient implements ClientEventsHandler, TelegramClient
}
@Override
public void handleEvents(boolean isClosed, long[] eventIds, TdApi.Object[] events,
int arrayOffset, int arrayLength) {
public void handleEvents(boolean isClosed, long[] eventIds, TdApi.Object[] events, int arrayOffset, int arrayLength) {
if (updatesHandler != null) {
LongArrayList idsToFilter = new LongArrayList(eventIds);
ObjectArrayList<TdApi.Object> eventsToFilter = new ObjectArrayList<>(events);
@ -115,7 +113,9 @@ public final class InternalClient implements ClientEventsHandler, TelegramClient
*/
private void handleEvent(long eventId, TdApi.Object event) {
logger.trace(TG_MARKER, "Received response {}: {}", eventId, event);
if (updatesHandler != null || updateHandler == null) throw new IllegalStateException();
if (updatesHandler != null || updateHandler == null) {
throw new IllegalStateException();
}
Handler<?> handler = eventId == 0 ? updateHandler : handlers.remove(eventId);
handleResponse(eventId, event, handler);
}
@ -127,7 +127,8 @@ public final class InternalClient implements ClientEventsHandler, TelegramClient
if (exceptionHandler != null) {
try {
exceptionHandler.onException(cause);
} catch (Throwable ignored) {}
} catch (Throwable ignored) {
}
}
}
@ -152,7 +153,9 @@ public final class InternalClient implements ClientEventsHandler, TelegramClient
}
private void createAndRegisterClient() {
if (clientId != null) throw new UnsupportedOperationException("Can't initialize the same client twice!");
if (clientId != null) {
throw new UnsupportedOperationException("Can't initialize the same client twice!");
}
clientId = NativeClientAccess.create();
clientManager.registerClient(clientId, this);
logger.info(TG_MARKER, "Registered new client {}", clientId);
@ -162,7 +165,8 @@ public final class InternalClient implements ClientEventsHandler, TelegramClient
}
@Override
public <R extends TdApi.Object> void send(Function<R> query, ResultHandler<R> resultHandler,
public <R extends TdApi.Object> void send(Function<R> query,
ResultHandler<R> resultHandler,
ExceptionHandler exceptionHandler) {
logger.trace(TG_MARKER, "Trying to send {}", query);
if (isClosedAndMaybeThrow(query)) {
@ -202,7 +206,6 @@ public final class InternalClient implements ClientEventsHandler, TelegramClient
}
/**
*
* @param function function used to check if the check will be enforced or not. Can be null
* @return true if closed
*/

View File

@ -39,7 +39,6 @@ public final class InternalClientManager implements AutoCloseable {
}
/**
*
* @return true if started as a result of this call
*/
public boolean startIfNeeded() {
@ -73,22 +72,30 @@ public final class InternalClientManager implements AutoCloseable {
return clientManager;
}
private void handleClientEvents(int clientId, boolean isClosed, long[] clientEventIds, TdApi.Object[] clientEvents,
int arrayOffset, int arrayLength) {
private void handleClientEvents(int clientId,
boolean isClosed,
long[] clientEventIds,
TdApi.Object[] clientEvents,
int arrayOffset,
int arrayLength) {
ClientEventsHandler handler = registeredClientEventHandlers.get(clientId);
if (handler != null) {
handler.handleEvents(isClosed, clientEventIds, clientEvents, arrayOffset, arrayLength);
} else {
java.util.List<DroppedEvent> droppedEvents
= getEffectivelyDroppedEvents(clientEventIds, clientEvents, arrayOffset, arrayLength);
java.util.List<DroppedEvent> droppedEvents = getEffectivelyDroppedEvents(clientEventIds,
clientEvents,
arrayOffset,
arrayLength
);
if (!droppedEvents.isEmpty()) {
logger.error("Unknown client id \"{}\"! {} events have been dropped!", clientId, droppedEvents.size());
for (DroppedEvent droppedEvent : droppedEvents) {
logger.error("The following event, with id \"{}\", has been dropped: {}",
droppedEvent.id,
droppedEvent.event);
droppedEvent.event
);
}
}
}
@ -103,8 +110,10 @@ public final class InternalClientManager implements AutoCloseable {
/**
* Get only events that have been dropped, ignoring synthetic errors related to the closure of a client
*/
private List<DroppedEvent> getEffectivelyDroppedEvents(long[] clientEventIds, TdApi.Object[] clientEvents,
int arrayOffset, int arrayLength) {
private List<DroppedEvent> getEffectivelyDroppedEvents(long[] clientEventIds,
TdApi.Object[] clientEvents,
int arrayOffset,
int arrayLength) {
java.util.List<DroppedEvent> droppedEvents = new ArrayList<>(arrayLength);
for (int i = arrayOffset; i < arrayOffset + arrayLength; i++) {
long id = clientEventIds[i];
@ -155,6 +164,7 @@ public final class InternalClientManager implements AutoCloseable {
}
private static final class DroppedEvent {
private final long id;
private final TdApi.Object event;

View File

@ -2,8 +2,8 @@ package it.tdlight.common.internal;
import it.tdlight.common.ClientEventsHandler;
import it.tdlight.common.ExceptionHandler;
import it.tdlight.common.Signal;
import it.tdlight.common.ReactiveTelegramClient;
import it.tdlight.common.Signal;
import it.tdlight.common.SignalListener;
import it.tdlight.jni.TdApi;
import it.tdlight.jni.TdApi.Error;
@ -20,7 +20,6 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import org.reactivestreams.Publisher;
import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -60,8 +59,7 @@ public final class InternalReactiveClient implements ClientEventsHandler, Reacti
}
@Override
public void handleEvents(boolean isClosed, long[] eventIds, TdApi.Object[] events,
int arrayOffset, int arrayLength) {
public void handleEvents(boolean isClosed, long[] eventIds, TdApi.Object[] events, int arrayOffset, int arrayLength) {
for (int i = arrayOffset; i < arrayOffset + arrayLength; i++) {
handleEvent(eventIds[i], events[i]);
}
@ -127,8 +125,11 @@ public final class InternalReactiveClient implements ClientEventsHandler, Reacti
}
}
if (timedOutHandlers.remove(eventId)) {
logger.trace(TG_MARKER, "Received event id \"{}\", but the event has been dropped because it"
+ "timed out some time ago! {}", eventId, event);
logger.trace(TG_MARKER,
"Received event id \"{}\", but the event has been dropped because it" + "timed out some time ago! {}",
eventId,
event
);
} else {
logger.error(TG_MARKER, "Unknown event id \"{}\", the event has been dropped! {}", eventId, event);
}

View File

@ -4,6 +4,7 @@ import it.tdlight.common.ExceptionHandler;
import it.tdlight.common.UpdatesHandler;
public final class MultiHandler {
private final UpdatesHandler updatesHandler;
private final ExceptionHandler exceptionHandler;

View File

@ -1,8 +1,8 @@
package it.tdlight.common.internal;
import it.tdlight.tdnative.NativeClient;
import it.tdlight.jni.TdApi;
import it.tdlight.jni.TdApi.Function;
import it.tdlight.tdnative.NativeClient;
final class NativeClientAccess extends NativeClient {

View File

@ -23,6 +23,7 @@ public final class ResponseReceiver extends Thread implements AutoCloseable {
));
private static final int MAX_EVENTS = 100;
private static final int[] originalSortingSource = new int[MAX_EVENTS];
static {
for (int i = 0; i < originalSortingSource.length; i++) {
originalSortingSource[i] = i;
@ -44,8 +45,7 @@ public final class ResponseReceiver extends Thread implements AutoCloseable {
private int clientEventsLastUsedLength = 0;
private final CountDownLatch closeWait = new CountDownLatch(1);
private final Set<Integer> registeredClients
= new ConcurrentHashMap<Integer, java.lang.Object>().keySet(new java.lang.Object());
private final Set<Integer> registeredClients = new ConcurrentHashMap<Integer, java.lang.Object>().keySet(new java.lang.Object());
public ResponseReceiver(EventsHandler eventsHandler) {
@ -72,8 +72,8 @@ public final class ResponseReceiver extends Thread implements AutoCloseable {
int[] sortIndex;
try {
boolean interrupted;
while (!(interrupted = Thread.interrupted())
&& ((!closeCalled.get() && !jvmShutdown.get()) || !registeredClients.isEmpty())) {
while (!(interrupted = Thread.interrupted()) && ((!closeCalled.get() && !jvmShutdown.get())
|| !registeredClients.isEmpty())) {
int resultsCount = NativeClientAccess.receive(clientIds, eventIds, events, 2.0 /*seconds*/);
if (resultsCount <= 0) {
@ -101,8 +101,7 @@ public final class ResponseReceiver extends Thread implements AutoCloseable {
if (clientEventIds[j] == 0
&& clientEvents[j].getConstructor() == TdApi.UpdateAuthorizationState.CONSTRUCTOR) {
TdApi.AuthorizationState authorizationState
= ((TdApi.UpdateAuthorizationState) clientEvents[j]).authorizationState;
TdApi.AuthorizationState authorizationState = ((TdApi.UpdateAuthorizationState) clientEvents[j]).authorizationState;
if (authorizationState.getConstructor() == TdApi.AuthorizationStateClosed.CONSTRUCTOR) {
lastClientClosed = true;
closedClients.add(clientId);
@ -111,8 +110,13 @@ public final class ResponseReceiver extends Thread implements AutoCloseable {
}
cleanClientEventsArray(lastClientIdEventsCount);
eventsHandler.handleClientEvents(clientId, lastClientClosed, clientEventIds, clientEvents,
0, lastClientIdEventsCount);
eventsHandler.handleClientEvents(clientId,
lastClientClosed,
clientEventIds,
clientEvents,
0,
lastClientIdEventsCount
);
}
if (i < resultsCount) {
@ -146,7 +150,8 @@ public final class ResponseReceiver extends Thread implements AutoCloseable {
}
Set<Integer> clientIds = eventsList.stream().map(e -> e.clientId).collect(Collectors.toSet());
for (int clientId : clientIds) {
List<Event> clientEventsList = eventsList.stream()
List<Event> clientEventsList = eventsList
.stream()
.filter(e -> e.clientId == clientId)
.collect(Collectors.toList());
boolean closed = false;
@ -156,8 +161,7 @@ public final class ResponseReceiver extends Thread implements AutoCloseable {
clientEvents[i] = e.event;
if (e.eventId == 0 && e.event.getConstructor() == TdApi.UpdateAuthorizationState.CONSTRUCTOR) {
TdApi.AuthorizationState authorizationState
= ((TdApi.UpdateAuthorizationState) e.event).authorizationState;
TdApi.AuthorizationState authorizationState = ((TdApi.UpdateAuthorizationState) e.event).authorizationState;
if (authorizationState.getConstructor() == TdApi.AuthorizationStateClosed.CONSTRUCTOR) {
closed = true;
closedClients.add(clientId);
@ -165,8 +169,13 @@ public final class ResponseReceiver extends Thread implements AutoCloseable {
}
}
cleanClientEventsArray(clientEventsList.size());
eventsHandler.handleClientEvents(clientId, closed, clientEventIds, clientEvents,
0, clientEventsList.size());
eventsHandler.handleClientEvents(clientId,
closed,
clientEventIds,
clientEvents,
0,
clientEventsList.size()
);
}
}
@ -206,7 +215,8 @@ public final class ResponseReceiver extends Thread implements AutoCloseable {
@SuppressWarnings("SameParameterValue")
private int[] generateSortIndex(int from, int to, int[] data) {
int[] sortedIndices = Arrays.copyOfRange(originalSortingSource, from, to);
it.unimi.dsi.fastutil.Arrays.mergeSort(from, to,
it.unimi.dsi.fastutil.Arrays.mergeSort(from,
to,
(o1, o2) -> Integer.compare(data[sortedIndices[o1]], data[sortedIndices[o2]]),
new IntSwapper(sortedIndices)
);

View File

@ -17,12 +17,11 @@
package it.tdlight.common.utils;
import java.io.IOException;
/**
* An exception that is thrown when the LoadLibrary class fails to load the library.
*/
public final class CantLoadLibrary extends Exception {
/**
* Creates a new CantLoadLibrary exception.
*/

View File

@ -19,13 +19,13 @@ package it.tdlight.common.utils;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.nio.ByteOrder;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.lang.reflect.InvocationTargetException;
/**
* The class to load the libraries needed to run Tdlib

View File

@ -1,8 +1,5 @@
package it.tdlight.common.utils;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.util.concurrent.locks.LockSupport;
public class SpinWaitSupport {

View File

@ -1,8 +1,8 @@
package it.tdlight.tdlib;
import it.tdlight.common.internal.CommonClientManager;
import it.tdlight.common.ReactiveTelegramClient;
import it.tdlight.common.TelegramClient;
import it.tdlight.common.internal.CommonClientManager;
/**
* Interface for interaction with TDLib.

View File

@ -1,8 +1,8 @@
package it.tdlight.tdlight;
import it.tdlight.common.internal.CommonClientManager;
import it.tdlight.common.ReactiveTelegramClient;
import it.tdlight.common.TelegramClient;
import it.tdlight.common.internal.CommonClientManager;
/**
* Interface for interaction with TDLight.

View File

@ -6,10 +6,13 @@ public class NativeClient {
protected static native int createNativeClient();
protected static native <R extends TdApi.Object> void nativeClientSend(int nativeClientId, long eventId,
protected static native <R extends TdApi.Object> void nativeClientSend(int nativeClientId,
long eventId,
TdApi.Function<R> function);
protected static native int nativeClientReceive(int[] clientIds, long[] eventIds, TdApi.Object[] events,
protected static native int nativeClientReceive(int[] clientIds,
long[] eventIds,
TdApi.Object[] events,
double timeout);
protected static native <R extends TdApi.Object> TdApi.Object nativeClientExecute(TdApi.Function<R> function);

View File

@ -1,7 +1,6 @@
package it.tdlight.tdnative;
import it.tdlight.jni.TdApi;
import java.util.Objects;
import java.util.function.Consumer;
/**