Use record classes

This commit is contained in:
AsamK 2021-10-24 22:26:12 +02:00
parent ce70a623c2
commit ce7aa580b6
66 changed files with 754 additions and 1877 deletions

View file

@ -26,11 +26,11 @@ public class JsonReceiveMessageHandler implements Manager.ReceiveMessageHandler
public void handleMessage(SignalServiceEnvelope envelope, SignalServiceContent content, Throwable exception) {
final var object = new HashMap<String, Object>();
if (exception != null) {
object.put("error", new JsonError(exception));
object.put("error", JsonError.from(exception));
}
if (envelope != null) {
object.put("envelope", new JsonMessageEnvelope(envelope, content, exception, m));
object.put("envelope", JsonMessageEnvelope.from(envelope, content, exception, m));
}
jsonWriter.write(object);

View file

@ -643,7 +643,7 @@ public class ReceiveMessageHandler implements Manager.ReceiveMessageHandler {
var group = m.getGroup(groupId);
if (group != null) {
writer.println("Name: {}", group.getTitle());
writer.println("Name: {}", group.title());
} else {
writer.println("Name: <Unknown group>");
}

View file

@ -66,21 +66,5 @@ public class GetUserStatusCommand implements JsonRpcLocalCommand {
}
}
private static final class JsonUserStatus {
public final String recipient;
public final String number;
public final String uuid;
public final boolean isRegistered;
public JsonUserStatus(String recipient, String number, String uuid, boolean isRegistered) {
this.recipient = recipient;
this.number = number;
this.uuid = uuid;
this.isRegistered = isRegistered;
}
}
private record JsonUserStatus(String recipient, String number, String uuid, boolean isRegistered) {}
}

View file

@ -69,7 +69,7 @@ public class JoinGroupCommand implements JsonRpcLocalCommand {
writer.println("Joined group \"{}\"", newGroupId.toBase64());
}
}
handleSendMessageResults(results.second().getResults());
handleSendMessageResults(results.second().results());
} catch (GroupPatchNotAcceptedException e) {
throw new UserErrorException("Failed to join group, maybe already a member");
} catch (IOException e) {

View file

@ -16,8 +16,7 @@ import java.util.Map;
public interface JsonRpcLocalCommand extends JsonRpcCommand<Map<String, Object>>, LocalCommand {
default TypeReference<Map<String, Object>> getRequestType() {
return new TypeReference<>() {
};
return new TypeReference<>() {};
}
default void handleCommand(

View file

@ -54,26 +54,5 @@ public class ListContactsCommand implements JsonRpcLocalCommand {
}
}
private static final class JsonContact {
public final String number;
public final String uuid;
public final String name;
public final boolean isBlocked;
public final int messageExpirationTime;
private JsonContact(
final String number,
final String uuid,
final String name,
final boolean isBlocked,
final int messageExpirationTime
) {
this.number = number;
this.uuid = uuid;
this.name = name;
this.isBlocked = isBlocked;
this.messageExpirationTime = messageExpirationTime;
}
}
private record JsonContact(String number, String uuid, String name, boolean isBlocked, int messageExpirationTime) {}
}

View file

@ -45,36 +45,21 @@ public class ListDevicesCommand implements JsonRpcLocalCommand {
if (outputWriter instanceof PlainTextWriter writer) {
for (var d : devices) {
writer.println("- Device {}{}:", d.getId(), (d.isThisDevice() ? " (this device)" : ""));
writer.println("- Device {}{}:", d.id(), (d.isThisDevice() ? " (this device)" : ""));
writer.indent(w -> {
w.println("Name: {}", d.getName());
w.println("Created: {}", DateUtils.formatTimestamp(d.getCreated()));
w.println("Last seen: {}", DateUtils.formatTimestamp(d.getLastSeen()));
w.println("Name: {}", d.name());
w.println("Created: {}", DateUtils.formatTimestamp(d.created()));
w.println("Last seen: {}", DateUtils.formatTimestamp(d.lastSeen()));
});
}
} else {
final var writer = (JsonWriter) outputWriter;
final var jsonDevices = devices.stream()
.map(d -> new JsonDevice(d.getId(), d.getName(), d.getCreated(), d.getLastSeen()))
.map(d -> new JsonDevice(d.id(), d.name(), d.created(), d.lastSeen()))
.collect(Collectors.toList());
writer.write(jsonDevices);
}
}
private static final class JsonDevice {
public final long id;
public final String name;
public final long createdTimestamp;
public final long lastSeenTimestamp;
private JsonDevice(
final long id, final String name, final long createdTimestamp, final long lastSeenTimestamp
) {
this.id = id;
this.name = name;
this.createdTimestamp = createdTimestamp;
this.lastSeenTimestamp = lastSeenTimestamp;
}
}
private record JsonDevice(long id, String name, long createdTimestamp, long lastSeenTimestamp) {}
}

View file

@ -50,25 +50,25 @@ public class ListGroupsCommand implements JsonRpcLocalCommand {
PlainTextWriter writer, Group group, boolean detailed
) {
if (detailed) {
final var groupInviteLink = group.getGroupInviteLinkUrl();
final var groupInviteLink = group.groupInviteLinkUrl();
writer.println(
"Id: {} Name: {} Description: {} Active: {} Blocked: {} Members: {} Pending members: {} Requesting members: {} Admins: {} Message expiration: {} Link: {}",
group.getGroupId().toBase64(),
group.getTitle(),
group.getDescription(),
group.groupId().toBase64(),
group.title(),
group.description(),
group.isMember(),
group.isBlocked(),
resolveMembers(group.getMembers()),
resolveMembers(group.getPendingMembers()),
resolveMembers(group.getRequestingMembers()),
resolveMembers(group.getAdminMembers()),
group.getMessageExpirationTimer() == 0 ? "disabled" : group.getMessageExpirationTimer() + "s",
resolveMembers(group.members()),
resolveMembers(group.pendingMembers()),
resolveMembers(group.requestingMembers()),
resolveMembers(group.adminMembers()),
group.messageExpirationTimer() == 0 ? "disabled" : group.messageExpirationTimer() + "s",
groupInviteLink == null ? '-' : groupInviteLink.getUrl());
} else {
writer.println("Id: {} Name: {} Active: {} Blocked: {}",
group.getGroupId().toBase64(),
group.getTitle(),
group.groupId().toBase64(),
group.title(),
group.isMember(),
group.isBlocked());
}
@ -83,21 +83,21 @@ public class ListGroupsCommand implements JsonRpcLocalCommand {
if (outputWriter instanceof JsonWriter jsonWriter) {
var jsonGroups = groups.stream().map(group -> {
final var groupInviteLink = group.getGroupInviteLinkUrl();
final var groupInviteLink = group.groupInviteLinkUrl();
return new JsonGroup(group.getGroupId().toBase64(),
group.getTitle(),
group.getDescription(),
return new JsonGroup(group.groupId().toBase64(),
group.title(),
group.description(),
group.isMember(),
group.isBlocked(),
group.getMessageExpirationTimer(),
resolveJsonMembers(group.getMembers()),
resolveJsonMembers(group.getPendingMembers()),
resolveJsonMembers(group.getRequestingMembers()),
resolveJsonMembers(group.getAdminMembers()),
group.getPermissionAddMember().name(),
group.getPermissionEditDetails().name(),
group.getPermissionSendMessage().name(),
group.messageExpirationTimer(),
resolveJsonMembers(group.members()),
resolveJsonMembers(group.pendingMembers()),
resolveJsonMembers(group.requestingMembers()),
resolveJsonMembers(group.adminMembers()),
group.permissionAddMember().name(),
group.permissionEditDetails().name(),
group.permissionSendMessage().name(),
groupInviteLink == null ? null : groupInviteLink.getUrl());
}).collect(Collectors.toList());
@ -111,66 +111,22 @@ public class ListGroupsCommand implements JsonRpcLocalCommand {
}
}
private static final class JsonGroup {
private record JsonGroup(
String id,
String name,
String description,
boolean isMember,
boolean isBlocked,
int messageExpirationTime,
Set<JsonGroupMember> members,
Set<JsonGroupMember> pendingMembers,
Set<JsonGroupMember> requestingMembers,
Set<JsonGroupMember> admins,
String permissionAddMember,
String permissionEditDetails,
String permissionSendMessage,
String groupInviteLink
) {}
public final String id;
public final String name;
public final String description;
public final boolean isMember;
public final boolean isBlocked;
public final int messageExpirationTime;
public final Set<JsonGroupMember> members;
public final Set<JsonGroupMember> pendingMembers;
public final Set<JsonGroupMember> requestingMembers;
public final Set<JsonGroupMember> admins;
public final String permissionAddMember;
public final String permissionEditDetails;
public final String permissionSendMessage;
public final String groupInviteLink;
public JsonGroup(
String id,
String name,
String description,
boolean isMember,
boolean isBlocked,
final int messageExpirationTime,
Set<JsonGroupMember> members,
Set<JsonGroupMember> pendingMembers,
Set<JsonGroupMember> requestingMembers,
Set<JsonGroupMember> admins,
final String permissionAddMember,
final String permissionEditDetails,
final String permissionSendMessage,
String groupInviteLink
) {
this.id = id;
this.name = name;
this.description = description;
this.isMember = isMember;
this.isBlocked = isBlocked;
this.messageExpirationTime = messageExpirationTime;
this.members = members;
this.pendingMembers = pendingMembers;
this.requestingMembers = requestingMembers;
this.admins = admins;
this.permissionAddMember = permissionAddMember;
this.permissionEditDetails = permissionEditDetails;
this.permissionSendMessage = permissionSendMessage;
this.groupInviteLink = groupInviteLink;
}
}
private static final class JsonGroupMember {
public final String number;
public final String uuid;
private JsonGroupMember(final String number, final String uuid) {
this.number = number;
this.uuid = uuid;
}
}
private record JsonGroupMember(String number, String uuid) {}
}

View file

@ -30,12 +30,12 @@ public class ListIdentitiesCommand implements JsonRpcLocalCommand {
}
private static void printIdentityFingerprint(PlainTextWriter writer, Manager m, Identity theirId) {
final SignalServiceAddress address = theirId.getRecipient().toSignalServiceAddress();
var digits = Util.formatSafetyNumber(theirId.getSafetyNumber());
final SignalServiceAddress address = theirId.recipient().toSignalServiceAddress();
var digits = Util.formatSafetyNumber(theirId.safetyNumber());
writer.println("{}: {} Added: {} Fingerprint: {} Safety Number: {}",
address.getNumber().orNull(),
theirId.getTrustLevel(),
theirId.getDateAdded(),
theirId.trustLevel(),
theirId.dateAdded(),
Hex.toString(theirId.getFingerprint()),
digits);
}
@ -66,9 +66,9 @@ public class ListIdentitiesCommand implements JsonRpcLocalCommand {
} else {
final var writer = (JsonWriter) outputWriter;
final var jsonIdentities = identities.stream().map(id -> {
final var address = id.getRecipient().toSignalServiceAddress();
var safetyNumber = Util.formatSafetyNumber(id.getSafetyNumber());
var scannableSafetyNumber = id.getScannableSafetyNumber();
final var address = id.recipient().toSignalServiceAddress();
var safetyNumber = Util.formatSafetyNumber(id.safetyNumber());
var scannableSafetyNumber = id.scannableSafetyNumber();
return new JsonIdentity(address.getNumber().orNull(),
address.getUuid().toString(),
Hex.toString(id.getFingerprint()),
@ -76,40 +76,21 @@ public class ListIdentitiesCommand implements JsonRpcLocalCommand {
scannableSafetyNumber == null
? null
: Base64.getEncoder().encodeToString(scannableSafetyNumber),
id.getTrustLevel().name(),
id.getDateAdded().getTime());
id.trustLevel().name(),
id.dateAdded().getTime());
}).collect(Collectors.toList());
writer.write(jsonIdentities);
}
}
private static final class JsonIdentity {
public final String number;
public final String uuid;
public final String fingerprint;
public final String safetyNumber;
public final String scannableSafetyNumber;
public final String trustLevel;
public final long addedTimestamp;
private JsonIdentity(
final String number,
final String uuid,
final String fingerprint,
final String safetyNumber,
final String scannableSafetyNumber,
final String trustLevel,
final long addedTimestamp
) {
this.number = number;
this.uuid = uuid;
this.fingerprint = fingerprint;
this.safetyNumber = safetyNumber;
this.scannableSafetyNumber = scannableSafetyNumber;
this.trustLevel = trustLevel;
this.addedTimestamp = addedTimestamp;
}
}
private record JsonIdentity(
String number,
String uuid,
String fingerprint,
String safetyNumber,
String scannableSafetyNumber,
String trustLevel,
long addedTimestamp
) {}
}

View file

@ -55,9 +55,9 @@ public class QuitGroupCommand implements JsonRpcLocalCommand {
try {
try {
final var results = m.quitGroup(groupId, groupAdmins);
final var timestamp = results.getTimestamp();
final var timestamp = results.timestamp();
outputResult(outputWriter, timestamp);
handleSendMessageResults(results.getResults());
handleSendMessageResults(results.results());
} catch (NotAGroupMemberException e) {
logger.info("User is not a group member");
}

View file

@ -61,19 +61,19 @@ public class ReceiveCommand implements ExtendedDbusCommand, LocalCommand {
if (outputWriter instanceof JsonWriter jsonWriter) {
dbusconnection.addSigHandler(Signal.MessageReceived.class, signal, messageReceived -> {
var envelope = new JsonMessageEnvelope(messageReceived);
var envelope = JsonMessageEnvelope.from(messageReceived);
final var object = Map.of("envelope", envelope);
jsonWriter.write(object);
});
dbusconnection.addSigHandler(Signal.ReceiptReceived.class, signal, receiptReceived -> {
var envelope = new JsonMessageEnvelope(receiptReceived);
var envelope = JsonMessageEnvelope.from(receiptReceived);
final var object = Map.of("envelope", envelope);
jsonWriter.write(object);
});
dbusconnection.addSigHandler(Signal.SyncMessageReceived.class, signal, syncReceived -> {
var envelope = new JsonMessageEnvelope(syncReceived);
var envelope = JsonMessageEnvelope.from(syncReceived);
final var object = Map.of("envelope", envelope);
jsonWriter.write(object);
});

View file

@ -56,8 +56,8 @@ public class RemoteDeleteCommand implements JsonRpcLocalCommand {
try {
final var results = m.sendRemoteDeleteMessage(targetTimestamp, recipientIdentifiers);
outputResult(outputWriter, results.getTimestamp());
ErrorUtils.handleSendMessageResults(results.getResults());
outputResult(outputWriter, results.timestamp());
ErrorUtils.handleSendMessageResults(results.results());
} catch (GroupNotFoundException | NotAGroupMemberException | GroupSendingNotAllowedException e) {
throw new UserErrorException(e.getMessage());
} catch (IOException e) {

View file

@ -102,8 +102,8 @@ public class SendCommand implements JsonRpcLocalCommand {
try {
var results = m.sendMessage(new Message(messageText, attachments), recipientIdentifiers);
outputResult(outputWriter, results.getTimestamp());
ErrorUtils.handleSendMessageResults(results.getResults());
outputResult(outputWriter, results.timestamp());
ErrorUtils.handleSendMessageResults(results.results());
} catch (AttachmentInvalidException | IOException e) {
throw new UnexpectedErrorException("Failed to send message: " + e.getMessage() + " (" + e.getClass()
.getSimpleName() + ")", e);

View file

@ -72,8 +72,8 @@ public class SendReactionCommand implements JsonRpcLocalCommand {
CommandUtil.getSingleRecipientIdentifier(targetAuthor, m.getSelfNumber()),
targetTimestamp,
recipientIdentifiers);
outputResult(outputWriter, results.getTimestamp());
ErrorUtils.handleSendMessageResults(results.getResults());
outputResult(outputWriter, results.timestamp());
ErrorUtils.handleSendMessageResults(results.results());
} catch (GroupNotFoundException | NotAGroupMemberException | GroupSendingNotAllowedException e) {
throw new UserErrorException(e.getMessage());
} catch (IOException e) {

View file

@ -127,8 +127,8 @@ public class UpdateGroupCommand implements JsonRpcLocalCommand {
var results = m.createGroup(groupName,
groupMembers,
groupAvatar == null ? null : new File(groupAvatar));
timestamp = results.second().getTimestamp();
ErrorUtils.handleSendMessageResults(results.second().getResults());
timestamp = results.second().timestamp();
ErrorUtils.handleSendMessageResults(results.second().results());
groupId = results.first();
groupName = null;
groupMembers = null;
@ -154,8 +154,8 @@ public class UpdateGroupCommand implements JsonRpcLocalCommand {
: groupSendMessagesPermission == GroupPermission.ONLY_ADMINS)
.build());
if (results != null) {
timestamp = results.getTimestamp();
ErrorUtils.handleSendMessageResults(results.getResults());
timestamp = results.timestamp();
ErrorUtils.handleSendMessageResults(results.results());
}
outputResult(outputWriter, timestamp, isNewGroup ? groupId : null);
} catch (AttachmentInvalidException e) {

View file

@ -321,9 +321,9 @@ public class DbusManagerImpl implements Manager {
final Message message, final Set<RecipientIdentifier> recipients
) throws IOException, AttachmentInvalidException, NotAGroupMemberException, GroupNotFoundException, GroupSendingNotAllowedException {
return handleMessage(recipients,
numbers -> signal.sendMessage(message.getMessageText(), message.getAttachments(), numbers),
() -> signal.sendNoteToSelfMessage(message.getMessageText(), message.getAttachments()),
groupId -> signal.sendGroupMessage(message.getMessageText(), message.getAttachments(), groupId));
numbers -> signal.sendMessage(message.messageText(), message.attachments(), numbers),
() -> signal.sendNoteToSelfMessage(message.messageText(), message.attachments()),
groupId -> signal.sendGroupMessage(message.messageText(), message.attachments(), groupId));
}
@Override

View file

@ -153,8 +153,8 @@ public class DbusSignalImpl implements Signal {
.map(RecipientIdentifier.class::cast)
.collect(Collectors.toSet()));
checkSendMessageResults(results.getTimestamp(), results.getResults());
return results.getTimestamp();
checkSendMessageResults(results.timestamp(), results.results());
return results.timestamp();
} catch (AttachmentInvalidException e) {
throw new Error.AttachmentInvalid(e.getMessage());
} catch (IOException e) {
@ -182,8 +182,8 @@ public class DbusSignalImpl implements Signal {
getSingleRecipientIdentifiers(recipients, m.getSelfNumber()).stream()
.map(RecipientIdentifier.class::cast)
.collect(Collectors.toSet()));
checkSendMessageResults(results.getTimestamp(), results.getResults());
return results.getTimestamp();
checkSendMessageResults(results.timestamp(), results.results());
return results.timestamp();
} catch (IOException e) {
throw new Error.Failure(e.getMessage());
} catch (GroupNotFoundException | NotAGroupMemberException | GroupSendingNotAllowedException e) {
@ -198,8 +198,8 @@ public class DbusSignalImpl implements Signal {
try {
final var results = m.sendRemoteDeleteMessage(targetSentTimestamp,
Set.of(new RecipientIdentifier.Group(getGroupId(groupId))));
checkSendMessageResults(results.getTimestamp(), results.getResults());
return results.getTimestamp();
checkSendMessageResults(results.timestamp(), results.results());
return results.timestamp();
} catch (IOException e) {
throw new Error.Failure(e.getMessage());
} catch (GroupNotFoundException | NotAGroupMemberException | GroupSendingNotAllowedException e) {
@ -236,8 +236,8 @@ public class DbusSignalImpl implements Signal {
getSingleRecipientIdentifiers(recipients, m.getSelfNumber()).stream()
.map(RecipientIdentifier.class::cast)
.collect(Collectors.toSet()));
checkSendMessageResults(results.getTimestamp(), results.getResults());
return results.getTimestamp();
checkSendMessageResults(results.timestamp(), results.results());
return results.timestamp();
} catch (IOException e) {
throw new Error.Failure(e.getMessage());
} catch (GroupNotFoundException | NotAGroupMemberException | GroupSendingNotAllowedException e) {
@ -303,8 +303,8 @@ public class DbusSignalImpl implements Signal {
try {
final var results = m.sendMessage(new Message(message, attachments),
Set.of(RecipientIdentifier.NoteToSelf.INSTANCE));
checkSendMessageResults(results.getTimestamp(), results.getResults());
return results.getTimestamp();
checkSendMessageResults(results.timestamp(), results.results());
return results.timestamp();
} catch (AttachmentInvalidException e) {
throw new Error.AttachmentInvalid(e.getMessage());
} catch (IOException e) {
@ -318,7 +318,7 @@ public class DbusSignalImpl implements Signal {
public void sendEndSessionMessage(final List<String> recipients) {
try {
final var results = m.sendEndSessionMessage(getSingleRecipientIdentifiers(recipients, m.getSelfNumber()));
checkSendMessageResults(results.getTimestamp(), results.getResults());
checkSendMessageResults(results.timestamp(), results.results());
} catch (IOException e) {
throw new Error.Failure(e.getMessage());
}
@ -329,8 +329,8 @@ public class DbusSignalImpl implements Signal {
try {
var results = m.sendMessage(new Message(message, attachments),
Set.of(new RecipientIdentifier.Group(getGroupId(groupId))));
checkSendMessageResults(results.getTimestamp(), results.getResults());
return results.getTimestamp();
checkSendMessageResults(results.timestamp(), results.results());
return results.timestamp();
} catch (IOException e) {
throw new Error.Failure(e.getMessage());
} catch (GroupNotFoundException | NotAGroupMemberException | GroupSendingNotAllowedException e) {
@ -354,8 +354,8 @@ public class DbusSignalImpl implements Signal {
getSingleRecipientIdentifier(targetAuthor, m.getSelfNumber()),
targetSentTimestamp,
Set.of(new RecipientIdentifier.Group(getGroupId(groupId))));
checkSendMessageResults(results.getTimestamp(), results.getResults());
return results.getTimestamp();
checkSendMessageResults(results.timestamp(), results.results());
return results.timestamp();
} catch (IOException e) {
throw new Error.Failure(e.getMessage());
} catch (GroupNotFoundException | NotAGroupMemberException | GroupSendingNotAllowedException e) {
@ -420,7 +420,7 @@ public class DbusSignalImpl implements Signal {
var groups = m.getGroups();
var ids = new ArrayList<byte[]>(groups.size());
for (var group : groups) {
ids.add(group.getGroupId().serialize());
ids.add(group.groupId().serialize());
}
return ids;
}
@ -444,10 +444,10 @@ public class DbusSignalImpl implements Signal {
@Override
public String getGroupName(final byte[] groupId) {
var group = m.getGroup(getGroupId(groupId));
if (group == null || group.getTitle() == null) {
if (group == null || group.title() == null) {
return "";
} else {
return group.getTitle();
return group.title();
}
}
@ -457,7 +457,7 @@ public class DbusSignalImpl implements Signal {
if (group == null) {
return List.of();
} else {
final var members = group.getMembers();
final var members = group.members();
return getRecipientStrings(members);
}
}
@ -478,7 +478,7 @@ public class DbusSignalImpl implements Signal {
final var memberIdentifiers = getSingleRecipientIdentifiers(members, m.getSelfNumber());
if (groupId == null) {
final var results = m.createGroup(name, memberIdentifiers, avatar == null ? null : new File(avatar));
checkSendMessageResults(results.second().getTimestamp(), results.second().getResults());
checkSendMessageResults(results.second().timestamp(), results.second().results());
return results.first().serialize();
} else {
final var results = m.updateGroup(getGroupId(groupId),
@ -488,7 +488,7 @@ public class DbusSignalImpl implements Signal {
.withAvatarFile(avatar == null ? null : new File(avatar))
.build());
if (results != null) {
checkSendMessageResults(results.getTimestamp(), results.getResults());
checkSendMessageResults(results.timestamp(), results.results());
}
return groupId;
}
@ -600,8 +600,8 @@ public class DbusSignalImpl implements Signal {
// all numbers the system knows
@Override
public List<String> listNumbers() {
return Stream.concat(m.getIdentities().stream().map(Identity::getRecipient),
m.getContacts().stream().map(Pair::first))
return Stream.concat(m.getIdentities().stream().map(Identity::recipient),
m.getContacts().stream().map(Pair::first))
.map(a -> a.getNumber().orElse(null))
.filter(Objects::nonNull)
.distinct()
@ -620,7 +620,7 @@ public class DbusSignalImpl implements Signal {
}
// Try profiles if no contact name was found
for (var identity : m.getIdentities()) {
final var address = identity.getRecipient();
final var address = identity.recipient();
var number = address.getNumber().orElse(null);
if (number != null) {
Profile profile = null;
@ -835,7 +835,7 @@ public class DbusSignalImpl implements Signal {
if (d.isThisDevice()) {
thisDevice = new DBusPath(deviceObjectPath);
}
this.devices.add(new StructDevice(new DBusPath(deviceObjectPath), d.getId(), emptyIfNull(d.getName())));
this.devices.add(new StructDevice(new DBusPath(deviceObjectPath), d.id(), emptyIfNull(d.name())));
});
}
@ -862,15 +862,15 @@ public class DbusSignalImpl implements Signal {
unExportGroups();
groups.forEach(g -> {
final var object = new DbusSignalGroupImpl(g.getGroupId());
final var object = new DbusSignalGroupImpl(g.groupId());
try {
connection.exportObject(object);
} catch (DBusException e) {
e.printStackTrace();
}
this.groups.add(new StructGroup(new DBusPath(object.getObjectPath()),
g.getGroupId().serialize(),
emptyIfNull(g.getTitle())));
g.groupId().serialize(),
emptyIfNull(g.title())));
});
}
@ -885,22 +885,22 @@ public class DbusSignalImpl implements Signal {
public DbusSignalDeviceImpl(final org.asamk.signal.manager.api.Device device) {
super.addPropertiesHandler(new DbusInterfacePropertiesHandler("org.asamk.Signal.Device",
List.of(new DbusProperty<>("Id", device::getId),
new DbusProperty<>("Name", () -> emptyIfNull(device.getName()), this::setDeviceName),
new DbusProperty<>("Created", device::getCreated),
new DbusProperty<>("LastSeen", device::getLastSeen))));
List.of(new DbusProperty<>("Id", device::id),
new DbusProperty<>("Name", () -> emptyIfNull(device.name()), this::setDeviceName),
new DbusProperty<>("Created", device::created),
new DbusProperty<>("LastSeen", device::lastSeen))));
this.device = device;
}
@Override
public String getObjectPath() {
return getDeviceObjectPath(objectPath, device.getId());
return getDeviceObjectPath(objectPath, device.id());
}
@Override
public void removeDevice() throws Error.Failure {
try {
m.removeLinkedDevices(device.getId());
m.removeLinkedDevices(device.id());
updateDevices();
} catch (IOException e) {
throw new Error.Failure(e.getMessage());
@ -929,36 +929,36 @@ public class DbusSignalImpl implements Signal {
this.groupId = groupId;
super.addPropertiesHandler(new DbusInterfacePropertiesHandler("org.asamk.Signal.Group",
List.of(new DbusProperty<>("Id", groupId::serialize),
new DbusProperty<>("Name", () -> emptyIfNull(getGroup().getTitle()), this::setGroupName),
new DbusProperty<>("Name", () -> emptyIfNull(getGroup().title()), this::setGroupName),
new DbusProperty<>("Description",
() -> emptyIfNull(getGroup().getDescription()),
() -> emptyIfNull(getGroup().description()),
this::setGroupDescription),
new DbusProperty<>("Avatar", this::setGroupAvatar),
new DbusProperty<>("IsBlocked", () -> getGroup().isBlocked(), this::setIsBlocked),
new DbusProperty<>("IsMember", () -> getGroup().isMember()),
new DbusProperty<>("IsAdmin", () -> getGroup().isAdmin()),
new DbusProperty<>("MessageExpirationTimer",
() -> getGroup().getMessageExpirationTimer(),
() -> getGroup().messageExpirationTimer(),
this::setMessageExpirationTime),
new DbusProperty<>("Members",
() -> new Variant<>(getRecipientStrings(getGroup().getMembers()), "as")),
() -> new Variant<>(getRecipientStrings(getGroup().members()), "as")),
new DbusProperty<>("PendingMembers",
() -> new Variant<>(getRecipientStrings(getGroup().getPendingMembers()), "as")),
() -> new Variant<>(getRecipientStrings(getGroup().pendingMembers()), "as")),
new DbusProperty<>("RequestingMembers",
() -> new Variant<>(getRecipientStrings(getGroup().getRequestingMembers()), "as")),
() -> new Variant<>(getRecipientStrings(getGroup().requestingMembers()), "as")),
new DbusProperty<>("Admins",
() -> new Variant<>(getRecipientStrings(getGroup().getAdminMembers()), "as")),
() -> new Variant<>(getRecipientStrings(getGroup().adminMembers()), "as")),
new DbusProperty<>("PermissionAddMember",
() -> getGroup().getPermissionAddMember().name(),
() -> getGroup().permissionAddMember().name(),
this::setGroupPermissionAddMember),
new DbusProperty<>("PermissionEditDetails",
() -> getGroup().getPermissionEditDetails().name(),
() -> getGroup().permissionEditDetails().name(),
this::setGroupPermissionEditDetails),
new DbusProperty<>("PermissionSendMessage",
() -> getGroup().getPermissionSendMessage().name(),
() -> getGroup().permissionSendMessage().name(),
this::setGroupPermissionSendMessage),
new DbusProperty<>("GroupInviteLink", () -> {
final var groupInviteLinkUrl = getGroup().getGroupInviteLinkUrl();
final var groupInviteLinkUrl = getGroup().groupInviteLinkUrl();
return groupInviteLinkUrl == null ? "" : groupInviteLinkUrl.getUrl();
}))));
}

View file

@ -1,43 +1,25 @@
package org.asamk.signal.json;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.whispersystems.signalservice.api.messages.SignalServiceAttachment;
class JsonAttachment {
@JsonProperty
final String contentType;
@JsonProperty
final String filename;
@JsonProperty
final String id;
@JsonProperty
final Long size;
JsonAttachment(SignalServiceAttachment attachment) {
this.contentType = attachment.getContentType();
record JsonAttachment(String contentType, String filename, String id, Long size) {
static JsonAttachment from(SignalServiceAttachment attachment) {
if (attachment.isPointer()) {
final var pointer = attachment.asPointer();
this.id = pointer.getRemoteId().toString();
this.filename = pointer.getFileName().orNull();
this.size = pointer.getSize().transform(Integer::longValue).orNull();
final var id = pointer.getRemoteId().toString();
final var filename = pointer.getFileName().orNull();
final var size = pointer.getSize().transform(Integer::longValue).orNull();
return new JsonAttachment(attachment.getContentType(), filename, id, size);
} else {
final var stream = attachment.asStream();
this.id = null;
this.filename = stream.getFileName().orNull();
this.size = stream.getLength();
final var filename = stream.getFileName().orNull();
final var size = stream.getLength();
return new JsonAttachment(attachment.getContentType(), filename, null, size);
}
}
JsonAttachment(String filename) {
this.filename = filename;
this.contentType = null;
this.id = null;
this.size = null;
static JsonAttachment from(String filename) {
return new JsonAttachment(filename, null, null, null);
}
}

View file

@ -1,7 +1,6 @@
package org.asamk.signal.json;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.whispersystems.signalservice.api.messages.calls.AnswerMessage;
import org.whispersystems.signalservice.api.messages.calls.BusyMessage;
@ -12,33 +11,19 @@ import org.whispersystems.signalservice.api.messages.calls.SignalServiceCallMess
import java.util.List;
class JsonCallMessage {
record JsonCallMessage(
@JsonInclude(JsonInclude.Include.NON_NULL) OfferMessage offerMessage,
@JsonInclude(JsonInclude.Include.NON_NULL) AnswerMessage answerMessage,
@JsonInclude(JsonInclude.Include.NON_NULL) BusyMessage busyMessage,
@JsonInclude(JsonInclude.Include.NON_NULL) HangupMessage hangupMessage,
@JsonInclude(JsonInclude.Include.NON_NULL) List<IceUpdateMessage> iceUpdateMessages
) {
@JsonProperty
@JsonInclude(JsonInclude.Include.NON_NULL)
final OfferMessage offerMessage;
@JsonProperty
@JsonInclude(JsonInclude.Include.NON_NULL)
final AnswerMessage answerMessage;
@JsonProperty
@JsonInclude(JsonInclude.Include.NON_NULL)
final BusyMessage busyMessage;
@JsonProperty
@JsonInclude(JsonInclude.Include.NON_NULL)
final HangupMessage hangupMessage;
@JsonProperty
@JsonInclude(JsonInclude.Include.NON_NULL)
final List<IceUpdateMessage> iceUpdateMessages;
JsonCallMessage(SignalServiceCallMessage callMessage) {
this.offerMessage = callMessage.getOfferMessage().orNull();
this.answerMessage = callMessage.getAnswerMessage().orNull();
this.busyMessage = callMessage.getBusyMessage().orNull();
this.hangupMessage = callMessage.getHangupMessage().orNull();
this.iceUpdateMessages = callMessage.getIceUpdateMessages().orNull();
static JsonCallMessage from(SignalServiceCallMessage callMessage) {
return new JsonCallMessage(callMessage.getOfferMessage().orNull(),
callMessage.getAnswerMessage().orNull(),
callMessage.getBusyMessage().orNull(),
callMessage.getHangupMessage().orNull(),
callMessage.getIceUpdateMessages().orNull());
}
}

View file

@ -1,48 +1,29 @@
package org.asamk.signal.json;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.asamk.signal.util.Util;
import org.whispersystems.signalservice.api.messages.shared.SharedContact;
public class JsonContactAddress {
public record JsonContactAddress(
SharedContact.PostalAddress.Type type,
String label,
String street,
String pobox,
String neighborhood,
String city,
String region,
String postcode,
String country
) {
@JsonProperty
private final SharedContact.PostalAddress.Type type;
@JsonProperty
private final String label;
@JsonProperty
private final String street;
@JsonProperty
private final String pobox;
@JsonProperty
private final String neighborhood;
@JsonProperty
private final String city;
@JsonProperty
private final String region;
@JsonProperty
private final String postcode;
@JsonProperty
private final String country;
public JsonContactAddress(SharedContact.PostalAddress address) {
type = address.getType();
label = Util.getStringIfNotBlank(address.getLabel());
street = Util.getStringIfNotBlank(address.getStreet());
pobox = Util.getStringIfNotBlank(address.getPobox());
neighborhood = Util.getStringIfNotBlank(address.getNeighborhood());
city = Util.getStringIfNotBlank(address.getCity());
region = Util.getStringIfNotBlank(address.getRegion());
postcode = Util.getStringIfNotBlank(address.getPostcode());
country = Util.getStringIfNotBlank(address.getCountry());
static JsonContactAddress from(SharedContact.PostalAddress address) {
return new JsonContactAddress(address.getType(),
Util.getStringIfNotBlank(address.getLabel()),
Util.getStringIfNotBlank(address.getStreet()),
Util.getStringIfNotBlank(address.getPobox()),
Util.getStringIfNotBlank(address.getNeighborhood()),
Util.getStringIfNotBlank(address.getCity()),
Util.getStringIfNotBlank(address.getRegion()),
Util.getStringIfNotBlank(address.getPostcode()),
Util.getStringIfNotBlank(address.getCountry()));
}
}

View file

@ -1,19 +1,10 @@
package org.asamk.signal.json;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.whispersystems.signalservice.api.messages.shared.SharedContact;
public class JsonContactAvatar {
public record JsonContactAvatar(JsonAttachment attachment, boolean isProfile) {
@JsonProperty
private final JsonAttachment attachment;
@JsonProperty
private final boolean isProfile;
public JsonContactAvatar(SharedContact.Avatar avatar) {
attachment = new JsonAttachment(avatar.getAttachment());
isProfile = avatar.isProfile();
static JsonContactAvatar from(SharedContact.Avatar avatar) {
return new JsonContactAvatar(JsonAttachment.from(avatar.getAttachment()), avatar.isProfile());
}
}

View file

@ -1,24 +1,11 @@
package org.asamk.signal.json;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.asamk.signal.util.Util;
import org.whispersystems.signalservice.api.messages.shared.SharedContact;
public class JsonContactEmail {
public record JsonContactEmail(String value, SharedContact.Email.Type type, String label) {
@JsonProperty
private final String value;
@JsonProperty
private final SharedContact.Email.Type type;
@JsonProperty
private final String label;
public JsonContactEmail(SharedContact.Email email) {
value = email.getValue();
type = email.getType();
label = Util.getStringIfNotBlank(email.getLabel());
static JsonContactEmail from(SharedContact.Email email) {
return new JsonContactEmail(email.getValue(), email.getType(), Util.getStringIfNotBlank(email.getLabel()));
}
}

View file

@ -1,36 +1,18 @@
package org.asamk.signal.json;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.asamk.signal.util.Util;
import org.whispersystems.signalservice.api.messages.shared.SharedContact;
public class JsonContactName {
public record JsonContactName(
String display, String given, String family, String prefix, String suffix, String middle
) {
@JsonProperty
private final String display;
@JsonProperty
private final String given;
@JsonProperty
private final String family;
@JsonProperty
private final String prefix;
@JsonProperty
private final String suffix;
@JsonProperty
private final String middle;
public JsonContactName(SharedContact.Name name) {
display = Util.getStringIfNotBlank(name.getDisplay());
given = Util.getStringIfNotBlank(name.getGiven());
family = Util.getStringIfNotBlank(name.getFamily());
prefix = Util.getStringIfNotBlank(name.getPrefix());
suffix = Util.getStringIfNotBlank(name.getSuffix());
middle = Util.getStringIfNotBlank(name.getMiddle());
static JsonContactName from(SharedContact.Name name) {
return new JsonContactName(Util.getStringIfNotBlank(name.getDisplay()),
Util.getStringIfNotBlank(name.getGiven()),
Util.getStringIfNotBlank(name.getFamily()),
Util.getStringIfNotBlank(name.getPrefix()),
Util.getStringIfNotBlank(name.getSuffix()),
Util.getStringIfNotBlank(name.getMiddle()));
}
}

View file

@ -1,24 +1,11 @@
package org.asamk.signal.json;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.asamk.signal.util.Util;
import org.whispersystems.signalservice.api.messages.shared.SharedContact;
public class JsonContactPhone {
public record JsonContactPhone(String value, SharedContact.Phone.Type type, String label) {
@JsonProperty
private final String value;
@JsonProperty
private final SharedContact.Phone.Type type;
@JsonProperty
private final String label;
public JsonContactPhone(SharedContact.Phone phone) {
value = phone.getValue();
type = phone.getType();
label = Util.getStringIfNotBlank(phone.getLabel());
static JsonContactPhone from(SharedContact.Phone phone) {
return new JsonContactPhone(phone.getValue(), phone.getType(), Util.getStringIfNotBlank(phone.getLabel()));
}
}

View file

@ -1,7 +1,6 @@
package org.asamk.signal.json;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.asamk.Signal;
import org.asamk.signal.manager.Manager;
@ -10,136 +9,124 @@ import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage;
import java.util.List;
import java.util.stream.Collectors;
class JsonDataMessage {
record JsonDataMessage(
long timestamp,
String message,
Integer expiresInSeconds,
@JsonInclude(JsonInclude.Include.NON_NULL) Boolean viewOnce,
@JsonInclude(JsonInclude.Include.NON_NULL) JsonReaction reaction,
@JsonInclude(JsonInclude.Include.NON_NULL) JsonQuote quote,
@JsonInclude(JsonInclude.Include.NON_NULL) List<JsonMention> mentions,
@JsonInclude(JsonInclude.Include.NON_NULL) List<JsonAttachment> attachments,
@JsonInclude(JsonInclude.Include.NON_NULL) JsonSticker sticker,
@JsonInclude(JsonInclude.Include.NON_NULL) JsonRemoteDelete remoteDelete,
@JsonInclude(JsonInclude.Include.NON_NULL) List<JsonSharedContact> contacts,
@JsonInclude(JsonInclude.Include.NON_NULL) JsonGroupInfo groupInfo
) {
@JsonProperty
final long timestamp;
@JsonProperty
final String message;
@JsonProperty
final Integer expiresInSeconds;
@JsonProperty
@JsonInclude(JsonInclude.Include.NON_NULL)
final Boolean viewOnce;
@JsonProperty
@JsonInclude(JsonInclude.Include.NON_NULL)
final JsonReaction reaction;
@JsonProperty
@JsonInclude(JsonInclude.Include.NON_NULL)
final JsonQuote quote;
@JsonProperty
@JsonInclude(JsonInclude.Include.NON_NULL)
final List<JsonMention> mentions;
@JsonProperty
@JsonInclude(JsonInclude.Include.NON_NULL)
final List<JsonAttachment> attachments;
@JsonProperty
@JsonInclude(JsonInclude.Include.NON_NULL)
final JsonSticker sticker;
@JsonProperty
@JsonInclude(JsonInclude.Include.NON_NULL)
final JsonRemoteDelete remoteDelete;
@JsonProperty
@JsonInclude(JsonInclude.Include.NON_NULL)
final List<JsonSharedContact> contacts;
@JsonProperty
@JsonInclude(JsonInclude.Include.NON_NULL)
final JsonGroupInfo groupInfo;
JsonDataMessage(SignalServiceDataMessage dataMessage, Manager m) {
this.timestamp = dataMessage.getTimestamp();
static JsonDataMessage from(SignalServiceDataMessage dataMessage, Manager m) {
final var timestamp = dataMessage.getTimestamp();
final JsonGroupInfo groupInfo;
if (dataMessage.getGroupContext().isPresent()) {
final var groupContext = dataMessage.getGroupContext().get();
if (groupContext.getGroupV1().isPresent()) {
var groupInfo = groupContext.getGroupV1().get();
this.groupInfo = new JsonGroupInfo(groupInfo);
var group = groupContext.getGroupV1().get();
groupInfo = JsonGroupInfo.from(group);
} else if (groupContext.getGroupV2().isPresent()) {
var groupInfo = groupContext.getGroupV2().get();
this.groupInfo = new JsonGroupInfo(groupInfo);
var group = groupContext.getGroupV2().get();
groupInfo = JsonGroupInfo.from(group);
} else {
this.groupInfo = null;
groupInfo = null;
}
} else {
this.groupInfo = null;
groupInfo = null;
}
this.message = dataMessage.getBody().orNull();
this.expiresInSeconds = dataMessage.getExpiresInSeconds();
this.viewOnce = dataMessage.isViewOnce();
this.reaction = dataMessage.getReaction().isPresent()
? new JsonReaction(dataMessage.getReaction().get(), m)
: null;
this.quote = dataMessage.getQuote().isPresent() ? new JsonQuote(dataMessage.getQuote().get(), m) : null;
final var message = dataMessage.getBody().orNull();
final var expiresInSeconds = dataMessage.getExpiresInSeconds();
final var viewOnce = dataMessage.isViewOnce();
final var reaction = dataMessage.getReaction().isPresent() ? JsonReaction.from(dataMessage.getReaction().get(),
m) : null;
final var quote = dataMessage.getQuote().isPresent() ? JsonQuote.from(dataMessage.getQuote().get(), m) : null;
final List<JsonMention> mentions;
if (dataMessage.getMentions().isPresent()) {
this.mentions = dataMessage.getMentions()
mentions = dataMessage.getMentions()
.get()
.stream()
.map(mention -> new JsonMention(mention, m))
.map(mention -> JsonMention.from(mention, m))
.collect(Collectors.toList());
} else {
this.mentions = List.of();
mentions = List.of();
}
remoteDelete = dataMessage.getRemoteDelete().isPresent() ? new JsonRemoteDelete(dataMessage.getRemoteDelete()
.get()) : null;
final var remoteDelete = dataMessage.getRemoteDelete().isPresent()
? JsonRemoteDelete.from(dataMessage.getRemoteDelete().get())
: null;
final List<JsonAttachment> attachments;
if (dataMessage.getAttachments().isPresent()) {
this.attachments = dataMessage.getAttachments()
attachments = dataMessage.getAttachments()
.get()
.stream()
.map(JsonAttachment::new)
.map(JsonAttachment::from)
.collect(Collectors.toList());
} else {
this.attachments = List.of();
attachments = List.of();
}
this.sticker = dataMessage.getSticker().isPresent() ? new JsonSticker(dataMessage.getSticker().get()) : null;
final var sticker = dataMessage.getSticker().isPresent()
? JsonSticker.from(dataMessage.getSticker().get())
: null;
final List<JsonSharedContact> contacts;
if (dataMessage.getSharedContacts().isPresent()) {
this.contacts = dataMessage.getSharedContacts()
contacts = dataMessage.getSharedContacts()
.get()
.stream()
.map(JsonSharedContact::new)
.map(JsonSharedContact::from)
.collect(Collectors.toList());
} else {
this.contacts = List.of();
contacts = List.of();
}
return new JsonDataMessage(timestamp,
message,
expiresInSeconds,
viewOnce,
reaction,
quote,
mentions,
attachments,
sticker,
remoteDelete,
contacts,
groupInfo);
}
public JsonDataMessage(Signal.MessageReceived messageReceived) {
timestamp = messageReceived.getTimestamp();
message = messageReceived.getMessage();
groupInfo = messageReceived.getGroupId().length > 0 ? new JsonGroupInfo(messageReceived.getGroupId()) : null;
expiresInSeconds = null;
viewOnce = null;
remoteDelete = null;
reaction = null; // TODO Replace these 5 with the proper commands
quote = null;
mentions = null;
sticker = null;
contacts = null;
attachments = messageReceived.getAttachments().stream().map(JsonAttachment::new).collect(Collectors.toList());
static JsonDataMessage from(Signal.MessageReceived messageReceived) {
return new JsonDataMessage(messageReceived.getTimestamp(),
messageReceived.getMessage(),
// TODO Replace these with the proper commands
null,
null,
null,
null,
null,
messageReceived.getAttachments().stream().map(JsonAttachment::from).collect(Collectors.toList()),
null,
null,
null,
messageReceived.getGroupId().length > 0 ? JsonGroupInfo.from(messageReceived.getGroupId()) : null);
}
public JsonDataMessage(Signal.SyncMessageReceived messageReceived) {
timestamp = messageReceived.getTimestamp();
message = messageReceived.getMessage();
groupInfo = messageReceived.getGroupId().length > 0 ? new JsonGroupInfo(messageReceived.getGroupId()) : null;
expiresInSeconds = null;
viewOnce = null;
remoteDelete = null;
reaction = null; // TODO Replace these 5 with the proper commands
quote = null;
mentions = null;
sticker = null;
contacts = null;
attachments = messageReceived.getAttachments().stream().map(JsonAttachment::new).collect(Collectors.toList());
static JsonDataMessage from(Signal.SyncMessageReceived messageReceived) {
return new JsonDataMessage(messageReceived.getTimestamp(),
messageReceived.getMessage(),
// TODO Replace these with the proper commands
null,
null,
null,
null,
null,
messageReceived.getAttachments().stream().map(JsonAttachment::from).collect(Collectors.toList()),
null,
null,
null,
messageReceived.getGroupId().length > 0 ? JsonGroupInfo.from(messageReceived.getGroupId()) : null);
}
}

View file

@ -1,17 +1,8 @@
package org.asamk.signal.json;
import com.fasterxml.jackson.annotation.JsonProperty;
public record JsonError(String message, String type) {
public class JsonError {
@JsonProperty
final String message;
@JsonProperty
final String type;
public JsonError(Throwable exception) {
this.message = exception.getMessage();
this.type = exception.getClass().getSimpleName();
public static JsonError from(Throwable exception) {
return new JsonError(exception.getMessage(), exception.getClass().getSimpleName());
}
}

View file

@ -1,7 +1,6 @@
package org.asamk.signal.json;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.asamk.signal.manager.groups.GroupUtils;
import org.asamk.signal.util.Util;
@ -12,48 +11,32 @@ import java.util.Base64;
import java.util.List;
import java.util.stream.Collectors;
class JsonGroupInfo {
record JsonGroupInfo(
String groupId,
String type,
@JsonInclude(JsonInclude.Include.NON_NULL) String name,
@JsonInclude(JsonInclude.Include.NON_NULL) List<String> members
) {
@JsonProperty
final String groupId;
@JsonProperty
final String type;
@JsonProperty
@JsonInclude(JsonInclude.Include.NON_NULL)
final String name;
@JsonProperty
@JsonInclude(JsonInclude.Include.NON_NULL)
final List<String> members;
JsonGroupInfo(SignalServiceGroup groupInfo) {
this.groupId = Base64.getEncoder().encodeToString(groupInfo.getGroupId());
this.type = groupInfo.getType().toString();
this.name = groupInfo.getName().orNull();
if (groupInfo.getMembers().isPresent()) {
this.members = groupInfo.getMembers()
.get()
.stream()
.map(Util::getLegacyIdentifier)
.collect(Collectors.toList());
} else {
this.members = null;
}
static JsonGroupInfo from(SignalServiceGroup groupInfo) {
return new JsonGroupInfo(Base64.getEncoder().encodeToString(groupInfo.getGroupId()),
groupInfo.getType().toString(),
groupInfo.getName().orNull(),
groupInfo.getMembers().isPresent() ? groupInfo.getMembers()
.get()
.stream()
.map(Util::getLegacyIdentifier)
.collect(Collectors.toList()) : null);
}
JsonGroupInfo(SignalServiceGroupV2 groupInfo) {
this.groupId = GroupUtils.getGroupIdV2(groupInfo.getMasterKey()).toBase64();
this.type = groupInfo.hasSignedGroupChange() ? "UPDATE" : "DELIVER";
this.members = null;
this.name = null;
static JsonGroupInfo from(SignalServiceGroupV2 groupInfo) {
return new JsonGroupInfo(GroupUtils.getGroupIdV2(groupInfo.getMasterKey()).toBase64(),
groupInfo.hasSignedGroupChange() ? "UPDATE" : "DELIVER",
null,
null);
}
JsonGroupInfo(byte[] groupId) {
this.groupId = Base64.getEncoder().encodeToString(groupId);
this.type = "DELIVER";
this.members = null;
this.name = null;
static JsonGroupInfo from(byte[] groupId) {
return new JsonGroupInfo(Base64.getEncoder().encodeToString(groupId), "DELIVER", null, null);
}
}

View file

@ -1,37 +1,19 @@
package org.asamk.signal.json;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.asamk.signal.manager.Manager;
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage;
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
import static org.asamk.signal.util.Util.getLegacyIdentifier;
public class JsonMention {
public record JsonMention(@Deprecated String name, String number, String uuid, int start, int length) {
@JsonProperty
@Deprecated
final String name;
@JsonProperty
final String number;
@JsonProperty
final String uuid;
@JsonProperty
final int start;
@JsonProperty
final int length;
JsonMention(SignalServiceDataMessage.Mention mention, Manager m) {
static JsonMention from(SignalServiceDataMessage.Mention mention, Manager m) {
final var address = m.resolveSignalServiceAddress(new SignalServiceAddress(mention.getUuid()));
this.name = getLegacyIdentifier(address);
this.number = address.getNumber().orNull();
this.uuid = address.getUuid().toString();
this.start = mention.getStart();
this.length = mention.getLength();
return new JsonMention(getLegacyIdentifier(address),
address.getNumber().orNull(),
address.getUuid().toString(),
mention.getStart(),
mention.getLength());
}
}

View file

@ -1,7 +1,6 @@
package org.asamk.signal.json;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.asamk.Signal;
import org.asamk.signal.manager.Manager;
@ -15,143 +14,133 @@ import java.util.List;
import static org.asamk.signal.util.Util.getLegacyIdentifier;
public class JsonMessageEnvelope {
public record JsonMessageEnvelope(
@Deprecated String source,
String sourceNumber,
String sourceUuid,
String sourceName,
Integer sourceDevice,
long timestamp,
@JsonInclude(JsonInclude.Include.NON_NULL) JsonDataMessage dataMessage,
@JsonInclude(JsonInclude.Include.NON_NULL) JsonSyncMessage syncMessage,
@JsonInclude(JsonInclude.Include.NON_NULL) JsonCallMessage callMessage,
@JsonInclude(JsonInclude.Include.NON_NULL) JsonReceiptMessage receiptMessage,
@JsonInclude(JsonInclude.Include.NON_NULL) JsonTypingMessage typingMessage
) {
@JsonProperty
@Deprecated
final String source;
@JsonProperty
final String sourceNumber;
@JsonProperty
final String sourceUuid;
@JsonProperty
final String sourceName;
@JsonProperty
final Integer sourceDevice;
@JsonProperty
final long timestamp;
@JsonProperty
@JsonInclude(JsonInclude.Include.NON_NULL)
final JsonDataMessage dataMessage;
@JsonProperty
@JsonInclude(JsonInclude.Include.NON_NULL)
final JsonSyncMessage syncMessage;
@JsonProperty
@JsonInclude(JsonInclude.Include.NON_NULL)
final JsonCallMessage callMessage;
@JsonProperty
@JsonInclude(JsonInclude.Include.NON_NULL)
final JsonReceiptMessage receiptMessage;
@JsonProperty
@JsonInclude(JsonInclude.Include.NON_NULL)
final JsonTypingMessage typingMessage;
public JsonMessageEnvelope(
public static JsonMessageEnvelope from(
SignalServiceEnvelope envelope, SignalServiceContent content, Throwable exception, Manager m
) {
final String source;
final String sourceNumber;
final String sourceUuid;
final Integer sourceDevice;
if (!envelope.isUnidentifiedSender() && envelope.hasSourceUuid()) {
var source = m.resolveSignalServiceAddress(envelope.getSourceAddress());
this.source = getLegacyIdentifier(source);
this.sourceNumber = source.getNumber().orNull();
this.sourceUuid = source.getUuid().toString();
this.sourceDevice = envelope.getSourceDevice();
final var sourceAddress = m.resolveSignalServiceAddress(envelope.getSourceAddress());
source = getLegacyIdentifier(sourceAddress);
sourceNumber = sourceAddress.getNumber().orNull();
sourceUuid = sourceAddress.getUuid().toString();
sourceDevice = envelope.getSourceDevice();
} else if (envelope.isUnidentifiedSender() && content != null) {
final var source = m.resolveSignalServiceAddress(content.getSender());
this.source = getLegacyIdentifier(source);
this.sourceNumber = source.getNumber().orNull();
this.sourceUuid = source.getUuid().toString();
this.sourceDevice = content.getSenderDevice();
final var sender = m.resolveSignalServiceAddress(content.getSender());
source = getLegacyIdentifier(sender);
sourceNumber = sender.getNumber().orNull();
sourceUuid = sender.getUuid().toString();
sourceDevice = content.getSenderDevice();
} else if (exception instanceof UntrustedIdentityException e) {
final var source = m.resolveSignalServiceAddress(e.getSender());
this.source = getLegacyIdentifier(source);
this.sourceNumber = source.getNumber().orNull();
this.sourceUuid = source.getUuid().toString();
this.sourceDevice = e.getSenderDevice();
final var sender = m.resolveSignalServiceAddress(e.getSender());
source = getLegacyIdentifier(sender);
sourceNumber = sender.getNumber().orNull();
sourceUuid = sender.getUuid().toString();
sourceDevice = e.getSenderDevice();
} else {
this.source = null;
this.sourceNumber = null;
this.sourceUuid = null;
this.sourceDevice = null;
source = null;
sourceNumber = null;
sourceUuid = null;
sourceDevice = null;
}
String name;
try {
name = m.getContactOrProfileName(RecipientIdentifier.Single.fromString(this.source, m.getSelfNumber()));
name = m.getContactOrProfileName(RecipientIdentifier.Single.fromString(source, m.getSelfNumber()));
} catch (InvalidNumberException | NullPointerException e) {
name = null;
}
this.sourceName = name;
this.timestamp = envelope.getTimestamp();
final var sourceName = name;
final var timestamp = envelope.getTimestamp();
final JsonReceiptMessage receiptMessage;
if (envelope.isReceipt()) {
this.receiptMessage = JsonReceiptMessage.deliveryReceipt(timestamp, List.of(timestamp));
receiptMessage = JsonReceiptMessage.deliveryReceipt(timestamp, List.of(timestamp));
} else if (content != null && content.getReceiptMessage().isPresent()) {
this.receiptMessage = new JsonReceiptMessage(content.getReceiptMessage().get());
receiptMessage = JsonReceiptMessage.from(content.getReceiptMessage().get());
} else {
this.receiptMessage = null;
receiptMessage = null;
}
this.typingMessage = content != null && content.getTypingMessage().isPresent()
? new JsonTypingMessage(content.getTypingMessage().get())
final var typingMessage = content != null && content.getTypingMessage().isPresent() ? JsonTypingMessage.from(
content.getTypingMessage().get()) : null;
final var dataMessage = content != null && content.getDataMessage().isPresent()
? JsonDataMessage.from(content.getDataMessage().get(), m)
: null;
final var syncMessage = content != null && content.getSyncMessage().isPresent()
? JsonSyncMessage.from(content.getSyncMessage().get(), m)
: null;
final var callMessage = content != null && content.getCallMessage().isPresent()
? JsonCallMessage.from(content.getCallMessage().get())
: null;
this.dataMessage = content != null && content.getDataMessage().isPresent()
? new JsonDataMessage(content.getDataMessage().get(), m)
: null;
this.syncMessage = content != null && content.getSyncMessage().isPresent()
? new JsonSyncMessage(content.getSyncMessage().get(), m)
: null;
this.callMessage = content != null && content.getCallMessage().isPresent()
? new JsonCallMessage(content.getCallMessage().get())
: null;
return new JsonMessageEnvelope(source,
sourceNumber,
sourceUuid,
sourceName,
sourceDevice,
timestamp,
dataMessage,
syncMessage,
callMessage,
receiptMessage,
typingMessage);
}
public JsonMessageEnvelope(Signal.MessageReceived messageReceived) {
source = messageReceived.getSender();
sourceNumber = null;
sourceUuid = null;
sourceName = null;
sourceDevice = null;
timestamp = messageReceived.getTimestamp();
receiptMessage = null;
dataMessage = new JsonDataMessage(messageReceived);
syncMessage = null;
callMessage = null;
typingMessage = null;
public static JsonMessageEnvelope from(Signal.MessageReceived messageReceived) {
return new JsonMessageEnvelope(messageReceived.getSource(),
null,
null,
null,
null,
messageReceived.getTimestamp(),
JsonDataMessage.from(messageReceived),
null,
null,
null,
null);
}
public JsonMessageEnvelope(Signal.ReceiptReceived receiptReceived) {
source = receiptReceived.getSender();
sourceNumber = null;
sourceUuid = null;
sourceName = null;
sourceDevice = null;
timestamp = receiptReceived.getTimestamp();
receiptMessage = JsonReceiptMessage.deliveryReceipt(timestamp, List.of(timestamp));
dataMessage = null;
syncMessage = null;
callMessage = null;
typingMessage = null;
public static JsonMessageEnvelope from(Signal.ReceiptReceived receiptReceived) {
return new JsonMessageEnvelope(receiptReceived.getSender(),
null,
null,
null,
null,
receiptReceived.getTimestamp(),
null,
null,
null,
JsonReceiptMessage.deliveryReceipt(receiptReceived.getTimestamp(),
List.of(receiptReceived.getTimestamp())),
null);
}
public JsonMessageEnvelope(Signal.SyncMessageReceived messageReceived) {
source = messageReceived.getSource();
sourceNumber = null;
sourceUuid = null;
sourceName = null;
sourceDevice = null;
timestamp = messageReceived.getTimestamp();
receiptMessage = null;
dataMessage = null;
syncMessage = new JsonSyncMessage(messageReceived);
callMessage = null;
typingMessage = null;
public static JsonMessageEnvelope from(Signal.SyncMessageReceived messageReceived) {
return new JsonMessageEnvelope(messageReceived.getSource(),
null,
null,
null,
null,
messageReceived.getTimestamp(),
null,
JsonSyncMessage.from(messageReceived),
null,
null,
null);
}
}

View file

@ -1,7 +1,6 @@
package org.asamk.signal.json;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.asamk.signal.manager.Manager;
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage;
@ -12,55 +11,41 @@ import java.util.stream.Collectors;
import static org.asamk.signal.util.Util.getLegacyIdentifier;
public class JsonQuote {
public record JsonQuote(
long id,
@Deprecated String author,
String authorNumber,
String authorUuid,
String text,
@JsonInclude(JsonInclude.Include.NON_NULL) List<JsonMention> mentions,
List<JsonQuotedAttachment> attachments
) {
@JsonProperty
final long id;
@JsonProperty
@Deprecated
final String author;
@JsonProperty
final String authorNumber;
@JsonProperty
final String authorUuid;
@JsonProperty
final String text;
@JsonProperty
@JsonInclude(JsonInclude.Include.NON_NULL)
final List<JsonMention> mentions;
@JsonProperty
final List<JsonQuotedAttachment> attachments;
JsonQuote(SignalServiceDataMessage.Quote quote, Manager m) {
this.id = quote.getId();
static JsonQuote from(SignalServiceDataMessage.Quote quote, Manager m) {
final var id = quote.getId();
final var address = m.resolveSignalServiceAddress(quote.getAuthor());
this.author = getLegacyIdentifier(address);
this.authorNumber = address.getNumber().orNull();
this.authorUuid = address.getUuid().toString();
this.text = quote.getText();
final var author = getLegacyIdentifier(address);
final var authorNumber = address.getNumber().orNull();
final var authorUuid = address.getUuid().toString();
final var text = quote.getText();
final List<JsonMention> mentions;
if (quote.getMentions() != null && quote.getMentions().size() > 0) {
this.mentions = quote.getMentions()
mentions = quote.getMentions()
.stream()
.map(quotedMention -> new JsonMention(quotedMention, m))
.map(quotedMention -> JsonMention.from(quotedMention, m))
.collect(Collectors.toList());
} else {
this.mentions = null;
mentions = null;
}
final List<JsonQuotedAttachment> attachments;
if (quote.getAttachments().size() > 0) {
this.attachments = quote.getAttachments()
.stream()
.map(JsonQuotedAttachment::new)
.collect(Collectors.toList());
attachments = quote.getAttachments().stream().map(JsonQuotedAttachment::from).collect(Collectors.toList());
} else {
this.attachments = new ArrayList<>();
attachments = new ArrayList<>();
}
return new JsonQuote(id, author, authorNumber, authorUuid, text, mentions, attachments);
}
}

View file

@ -1,29 +1,22 @@
package org.asamk.signal.json;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage;
public class JsonQuotedAttachment {
public record JsonQuotedAttachment(
String contentType, String filename, @JsonInclude(JsonInclude.Include.NON_NULL) JsonAttachment thumbnail
) {
@JsonProperty
final String contentType;
@JsonProperty
final String filename;
@JsonProperty
@JsonInclude(JsonInclude.Include.NON_NULL)
final JsonAttachment thumbnail;
JsonQuotedAttachment(SignalServiceDataMessage.Quote.QuotedAttachment quotedAttachment) {
contentType = quotedAttachment.getContentType();
filename = quotedAttachment.getFileName();
static JsonQuotedAttachment from(SignalServiceDataMessage.Quote.QuotedAttachment quotedAttachment) {
final var contentType = quotedAttachment.getContentType();
final var filename = quotedAttachment.getFileName();
final JsonAttachment thumbnail;
if (quotedAttachment.getThumbnail() != null) {
thumbnail = new JsonAttachment(quotedAttachment.getThumbnail());
thumbnail = JsonAttachment.from(quotedAttachment.getThumbnail());
} else {
thumbnail = null;
}
return new JsonQuotedAttachment(contentType, filename, thumbnail);
}
}

View file

@ -1,40 +1,32 @@
package org.asamk.signal.json;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.asamk.signal.manager.Manager;
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage.Reaction;
import static org.asamk.signal.util.Util.getLegacyIdentifier;
public class JsonReaction {
public record JsonReaction(
String emoji,
@Deprecated String targetAuthor,
String targetAuthorNumber,
String targetAuthorUuid,
long targetSentTimestamp,
boolean isRemove
) {
@JsonProperty
final String emoji;
@JsonProperty
@Deprecated
final String targetAuthor;
@JsonProperty
final String targetAuthorNumber;
@JsonProperty
final String targetAuthorUuid;
@JsonProperty
final long targetSentTimestamp;
@JsonProperty
final boolean isRemove;
JsonReaction(Reaction reaction, Manager m) {
this.emoji = reaction.getEmoji();
static JsonReaction from(Reaction reaction, Manager m) {
final var emoji = reaction.getEmoji();
final var address = m.resolveSignalServiceAddress(reaction.getTargetAuthor());
this.targetAuthor = getLegacyIdentifier(address);
this.targetAuthorNumber = address.getNumber().orNull();
this.targetAuthorUuid = address.getUuid().toString();
this.targetSentTimestamp = reaction.getTargetSentTimestamp();
this.isRemove = reaction.isRemove();
final var targetAuthor = getLegacyIdentifier(address);
final var targetAuthorNumber = address.getNumber().orNull();
final var targetAuthorUuid = address.getUuid().toString();
final var targetSentTimestamp = reaction.getTargetSentTimestamp();
final var isRemove = reaction.isRemove();
return new JsonReaction(emoji,
targetAuthor,
targetAuthorNumber,
targetAuthorUuid,
targetSentTimestamp,
isRemove);
}
}

View file

@ -1,39 +1,17 @@
package org.asamk.signal.json;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.whispersystems.signalservice.api.messages.SignalServiceReceiptMessage;
import java.util.List;
class JsonReceiptMessage {
record JsonReceiptMessage(long when, boolean isDelivery, boolean isRead, List<Long> timestamps) {
@JsonProperty
final long when;
@JsonProperty
final boolean isDelivery;
@JsonProperty
final boolean isRead;
@JsonProperty
final List<Long> timestamps;
JsonReceiptMessage(SignalServiceReceiptMessage receiptMessage) {
this.when = receiptMessage.getWhen();
this.isDelivery = receiptMessage.isDeliveryReceipt();
this.isRead = receiptMessage.isReadReceipt();
this.timestamps = receiptMessage.getTimestamps();
}
private JsonReceiptMessage(
final long when, final boolean isDelivery, final boolean isRead, final List<Long> timestamps
) {
this.when = when;
this.isDelivery = isDelivery;
this.isRead = isRead;
this.timestamps = timestamps;
static JsonReceiptMessage from(SignalServiceReceiptMessage receiptMessage) {
final var when = receiptMessage.getWhen();
final var isDelivery = receiptMessage.isDeliveryReceipt();
final var isRead = receiptMessage.isReadReceipt();
final var timestamps = receiptMessage.getTimestamps();
return new JsonReceiptMessage(when, isDelivery, isRead, timestamps);
}
static JsonReceiptMessage deliveryReceipt(final long when, final List<Long> timestamps) {

View file

@ -1,15 +1,10 @@
package org.asamk.signal.json;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage;
class JsonRemoteDelete {
record JsonRemoteDelete(long timestamp) {
@JsonProperty
final long timestamp;
JsonRemoteDelete(SignalServiceDataMessage.RemoteDelete remoteDelete) {
this.timestamp = remoteDelete.getTargetSentTimestamp();
static JsonRemoteDelete from(SignalServiceDataMessage.RemoteDelete remoteDelete) {
return new JsonRemoteDelete(remoteDelete.getTargetSentTimestamp());
}
}

View file

@ -1,62 +1,45 @@
package org.asamk.signal.json;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.whispersystems.signalservice.api.messages.shared.SharedContact;
import java.util.List;
import java.util.stream.Collectors;
public class JsonSharedContact {
public record JsonSharedContact(
JsonContactName name,
JsonContactAvatar avatar,
@JsonInclude(JsonInclude.Include.NON_NULL) List<JsonContactPhone> phone,
@JsonInclude(JsonInclude.Include.NON_NULL) List<JsonContactEmail> email,
@JsonInclude(JsonInclude.Include.NON_NULL) List<JsonContactAddress> address,
String organization
) {
@JsonProperty
final JsonContactName name;
static JsonSharedContact from(SharedContact contact) {
final var name = JsonContactName.from(contact.getName());
final var avatar = contact.getAvatar().isPresent() ? JsonContactAvatar.from(contact.getAvatar().get()) : null;
@JsonProperty
final JsonContactAvatar avatar;
final var phone = contact.getPhone().isPresent() ? contact.getPhone()
.get()
.stream()
.map(JsonContactPhone::from)
.collect(Collectors.toList()) : null;
@JsonProperty
@JsonInclude(JsonInclude.Include.NON_NULL)
final List<JsonContactPhone> phone;
final var email = contact.getEmail().isPresent() ? contact.getEmail()
.get()
.stream()
.map(JsonContactEmail::from)
.collect(Collectors.toList()) : null;
@JsonProperty
@JsonInclude(JsonInclude.Include.NON_NULL)
final List<JsonContactEmail> email;
final var address = contact.getAddress().isPresent() ? contact.getAddress()
.get()
.stream()
.map(JsonContactAddress::from)
.collect(Collectors.toList()) : null;
@JsonProperty
@JsonInclude(JsonInclude.Include.NON_NULL)
final List<JsonContactAddress> address;
final var organization = contact.getOrganization().orNull();
@JsonProperty
final String organization;
public JsonSharedContact(SharedContact contact) {
name = new JsonContactName(contact.getName());
if (contact.getAvatar().isPresent()) {
avatar = new JsonContactAvatar(contact.getAvatar().get());
} else {
avatar = null;
}
if (contact.getPhone().isPresent()) {
phone = contact.getPhone().get().stream().map(JsonContactPhone::new).collect(Collectors.toList());
} else {
phone = null;
}
if (contact.getEmail().isPresent()) {
email = contact.getEmail().get().stream().map(JsonContactEmail::new).collect(Collectors.toList());
} else {
email = null;
}
if (contact.getAddress().isPresent()) {
address = contact.getAddress().get().stream().map(JsonContactAddress::new).collect(Collectors.toList());
} else {
address = null;
}
organization = contact.getOrganization().orNull();
return new JsonSharedContact(name, avatar, phone, email, address, organization);
}
}

View file

@ -1,25 +1,15 @@
package org.asamk.signal.json;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage;
import java.util.Base64;
public class JsonSticker {
public record JsonSticker(String packId, String packKey, int stickerId) {
@JsonProperty
final String packId;
@JsonProperty
final String packKey;
@JsonProperty
final int stickerId;
public JsonSticker(SignalServiceDataMessage.Sticker sticker) {
this.packId = Base64.getEncoder().encodeToString(sticker.getPackId());
this.packKey = Base64.getEncoder().encodeToString(sticker.getPackKey());
this.stickerId = sticker.getStickerId();
static JsonSticker from(SignalServiceDataMessage.Sticker sticker) {
final var packId = Base64.getEncoder().encodeToString(sticker.getPackId());
final var packKey = Base64.getEncoder().encodeToString(sticker.getPackKey());
final var stickerId = sticker.getStickerId();
return new JsonSticker(packId, packKey, stickerId);
}
}

View file

@ -1,6 +1,6 @@
package org.asamk.signal.json;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonUnwrapped;
import org.asamk.Signal;
import org.asamk.signal.manager.Manager;
@ -8,37 +8,30 @@ import org.whispersystems.signalservice.api.messages.multidevice.SentTranscriptM
import static org.asamk.signal.util.Util.getLegacyIdentifier;
class JsonSyncDataMessage extends JsonDataMessage {
@JsonProperty
@Deprecated
final String destination;
@JsonProperty
final String destinationNumber;
@JsonProperty
final String destinationUuid;
JsonSyncDataMessage(SentTranscriptMessage transcriptMessage, Manager m) {
super(transcriptMessage.getMessage(), m);
record JsonSyncDataMessage(
@Deprecated String destination,
String destinationNumber,
String destinationUuid,
@JsonUnwrapped JsonDataMessage dataMessage
) {
static JsonSyncDataMessage from(SentTranscriptMessage transcriptMessage, Manager m) {
if (transcriptMessage.getDestination().isPresent()) {
final var address = transcriptMessage.getDestination().get();
this.destination = getLegacyIdentifier(address);
this.destinationNumber = address.getNumber().orNull();
this.destinationUuid = address.getUuid().toString();
return new JsonSyncDataMessage(getLegacyIdentifier(address),
address.getNumber().orNull(),
address.getUuid().toString(),
JsonDataMessage.from(transcriptMessage.getMessage(), m));
} else {
this.destination = null;
this.destinationNumber = null;
this.destinationUuid = null;
return new JsonSyncDataMessage(null, null, null, JsonDataMessage.from(transcriptMessage.getMessage(), m));
}
}
JsonSyncDataMessage(Signal.SyncMessageReceived messageReceived) {
super(messageReceived);
this.destination = messageReceived.getDestination();
this.destinationNumber = null;
this.destinationUuid = null;
static JsonSyncDataMessage from(Signal.SyncMessageReceived messageReceived) {
return new JsonSyncDataMessage(messageReceived.getDestination(),
null,
null,
JsonDataMessage.from(messageReceived));
}
}

View file

@ -1,7 +1,6 @@
package org.asamk.signal.json;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.asamk.Signal;
import org.asamk.signal.manager.Manager;
@ -18,76 +17,72 @@ enum JsonSyncMessageType {
REQUEST_SYNC
}
class JsonSyncMessage {
record JsonSyncMessage(
@JsonInclude(JsonInclude.Include.NON_NULL) JsonSyncDataMessage sentMessage,
@JsonInclude(JsonInclude.Include.NON_NULL) List<String> blockedNumbers,
@JsonInclude(JsonInclude.Include.NON_NULL) List<String> blockedGroupIds,
@JsonInclude(JsonInclude.Include.NON_NULL) List<JsonSyncReadMessage> readMessages,
@JsonInclude(JsonInclude.Include.NON_NULL) JsonSyncMessageType type
) {
@JsonProperty
@JsonInclude(JsonInclude.Include.NON_NULL)
final JsonSyncDataMessage sentMessage;
JsonSyncMessage(
final JsonSyncDataMessage sentMessage,
final List<String> blockedNumbers,
final List<String> blockedGroupIds,
final List<JsonSyncReadMessage> readMessages,
final JsonSyncMessageType type
) {
this.sentMessage = sentMessage;
this.blockedNumbers = blockedNumbers;
this.blockedGroupIds = blockedGroupIds;
this.readMessages = readMessages;
this.type = type;
}
@JsonProperty
@JsonInclude(JsonInclude.Include.NON_NULL)
final List<String> blockedNumbers;
@JsonProperty
@JsonInclude(JsonInclude.Include.NON_NULL)
final List<String> blockedGroupIds;
@JsonProperty
@JsonInclude(JsonInclude.Include.NON_NULL)
final List<JsonSyncReadMessage> readMessages;
@JsonProperty
@JsonInclude(JsonInclude.Include.NON_NULL)
final JsonSyncMessageType type;
JsonSyncMessage(SignalServiceSyncMessage syncMessage, Manager m) {
this.sentMessage = syncMessage.getSent().isPresent()
? new JsonSyncDataMessage(syncMessage.getSent().get(), m)
: null;
static JsonSyncMessage from(SignalServiceSyncMessage syncMessage, Manager m) {
final var sentMessage = syncMessage.getSent().isPresent() ? JsonSyncDataMessage.from(syncMessage.getSent()
.get(), m) : null;
final List<String> blockedNumbers;
final List<String> blockedGroupIds;
if (syncMessage.getBlockedList().isPresent()) {
final var base64 = Base64.getEncoder();
this.blockedNumbers = syncMessage.getBlockedList()
blockedNumbers = syncMessage.getBlockedList()
.get()
.getAddresses()
.stream()
.map(Util::getLegacyIdentifier)
.collect(Collectors.toList());
this.blockedGroupIds = syncMessage.getBlockedList()
blockedGroupIds = syncMessage.getBlockedList()
.get()
.getGroupIds()
.stream()
.map(base64::encodeToString)
.collect(Collectors.toList());
} else {
this.blockedNumbers = null;
this.blockedGroupIds = null;
}
if (syncMessage.getRead().isPresent()) {
this.readMessages = syncMessage.getRead()
.get()
.stream()
.map(JsonSyncReadMessage::new)
.collect(Collectors.toList());
} else {
this.readMessages = null;
blockedNumbers = null;
blockedGroupIds = null;
}
final var readMessages = syncMessage.getRead().isPresent() ? syncMessage.getRead()
.get()
.stream()
.map(JsonSyncReadMessage::from)
.collect(Collectors.toList()) : null;
final JsonSyncMessageType type;
if (syncMessage.getContacts().isPresent()) {
this.type = JsonSyncMessageType.CONTACTS_SYNC;
type = JsonSyncMessageType.CONTACTS_SYNC;
} else if (syncMessage.getGroups().isPresent()) {
this.type = JsonSyncMessageType.GROUPS_SYNC;
type = JsonSyncMessageType.GROUPS_SYNC;
} else if (syncMessage.getRequest().isPresent()) {
this.type = JsonSyncMessageType.REQUEST_SYNC;
type = JsonSyncMessageType.REQUEST_SYNC;
} else {
this.type = null;
type = null;
}
return new JsonSyncMessage(sentMessage, blockedNumbers, blockedGroupIds, readMessages, type);
}
JsonSyncMessage(Signal.SyncMessageReceived messageReceived) {
this.sentMessage = new JsonSyncDataMessage(messageReceived);
this.blockedNumbers = null;
this.blockedGroupIds = null;
this.readMessages = null;
this.type = null;
static JsonSyncMessage from(Signal.SyncMessageReceived messageReceived) {
return new JsonSyncMessage(JsonSyncDataMessage.from(messageReceived), null, null, null, null);
}
}

View file

@ -1,31 +1,19 @@
package org.asamk.signal.json;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.whispersystems.signalservice.api.messages.multidevice.ReadMessage;
import static org.asamk.signal.util.Util.getLegacyIdentifier;
class JsonSyncReadMessage {
record JsonSyncReadMessage(
@Deprecated String sender, String senderNumber, String senderUuid, long timestamp
) {
@JsonProperty
@Deprecated
final String sender;
@JsonProperty
final String senderNumber;
@JsonProperty
final String senderUuid;
@JsonProperty
final long timestamp;
public JsonSyncReadMessage(final ReadMessage readMessage) {
final var sender = readMessage.getSender();
this.sender = getLegacyIdentifier(sender);
this.senderNumber = sender.getNumber().orNull();
this.senderUuid = sender.getUuid().toString();
this.timestamp = readMessage.getTimestamp();
static JsonSyncReadMessage from(final ReadMessage readMessage) {
final var senderAddress = readMessage.getSender();
final var sender = getLegacyIdentifier(senderAddress);
final var senderNumber = senderAddress.getNumber().orNull();
final var senderUuid = senderAddress.getUuid().toString();
final var timestamp = readMessage.getTimestamp();
return new JsonSyncReadMessage(sender, senderNumber, senderUuid, timestamp);
}
}

View file

@ -1,28 +1,26 @@
package org.asamk.signal.json;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.whispersystems.signalservice.api.messages.SignalServiceTypingMessage;
import java.util.Base64;
class JsonTypingMessage {
record JsonTypingMessage(
String action, long timestamp, @JsonInclude(JsonInclude.Include.NON_NULL) String groupId
) {
@JsonProperty
final String action;
JsonTypingMessage(final String action, final long timestamp, final String groupId) {
this.action = action;
this.timestamp = timestamp;
this.groupId = groupId;
}
@JsonProperty
final long timestamp;
@JsonProperty
@JsonInclude(JsonInclude.Include.NON_NULL)
final String groupId;
JsonTypingMessage(SignalServiceTypingMessage typingMessage) {
this.action = typingMessage.getAction().name();
this.timestamp = typingMessage.getTimestamp();
static JsonTypingMessage from(SignalServiceTypingMessage typingMessage) {
final var action = typingMessage.getAction().name();
final var timestamp = typingMessage.getTimestamp();
final var encoder = Base64.getEncoder();
this.groupId = typingMessage.getGroupId().transform(encoder::encodeToString).orNull();
final var groupId = typingMessage.getGroupId().transform(encoder::encodeToString).orNull();
return new JsonTypingMessage(action, timestamp, groupId);
}
}