1 package org
.asamk
.signal
.manager
.storage
.groups
;
3 import com
.fasterxml
.jackson
.annotation
.JsonIgnore
;
4 import com
.fasterxml
.jackson
.annotation
.JsonProperty
;
5 import com
.fasterxml
.jackson
.core
.JsonGenerator
;
6 import com
.fasterxml
.jackson
.core
.JsonParser
;
7 import com
.fasterxml
.jackson
.databind
.DeserializationContext
;
8 import com
.fasterxml
.jackson
.databind
.JsonDeserializer
;
9 import com
.fasterxml
.jackson
.databind
.JsonNode
;
10 import com
.fasterxml
.jackson
.databind
.JsonSerializer
;
11 import com
.fasterxml
.jackson
.databind
.ObjectMapper
;
12 import com
.fasterxml
.jackson
.databind
.SerializerProvider
;
13 import com
.fasterxml
.jackson
.databind
.annotation
.JsonDeserialize
;
14 import com
.fasterxml
.jackson
.databind
.annotation
.JsonSerialize
;
16 import org
.asamk
.signal
.manager
.groups
.GroupId
;
17 import org
.asamk
.signal
.manager
.groups
.GroupIdV1
;
18 import org
.asamk
.signal
.manager
.groups
.GroupIdV2
;
19 import org
.asamk
.signal
.manager
.groups
.GroupInviteLinkUrl
;
20 import org
.asamk
.signal
.manager
.groups
.GroupUtils
;
21 import org
.whispersystems
.signalservice
.api
.push
.SignalServiceAddress
;
23 import java
.io
.IOException
;
24 import java
.util
.Collection
;
25 import java
.util
.HashSet
;
27 import java
.util
.UUID
;
29 public class GroupInfoV1
extends GroupInfo
{
31 private static final ObjectMapper jsonProcessor
= new ObjectMapper();
33 private final GroupIdV1 groupId
;
35 private GroupIdV2 expectedV2Id
;
41 @JsonDeserialize(using
= MembersDeserializer
.class)
42 @JsonSerialize(using
= MembersSerializer
.class)
43 public Set
<SignalServiceAddress
> members
= new HashSet
<>();
46 @JsonProperty(defaultValue
= "0")
47 public int messageExpirationTime
;
48 @JsonProperty(defaultValue
= "false")
49 public boolean blocked
;
51 public Integer inboxPosition
;
52 @JsonProperty(defaultValue
= "false")
53 public boolean archived
;
55 public GroupInfoV1(GroupIdV1 groupId
) {
56 this.groupId
= groupId
;
60 @JsonProperty("groupId") byte[] groupId
,
61 @JsonProperty("expectedV2Id") byte[] expectedV2Id
,
62 @JsonProperty("name") String name
,
63 @JsonProperty("members") Collection
<SignalServiceAddress
> members
,
64 @JsonProperty("avatarId") long _ignored_avatarId
,
65 @JsonProperty("color") String color
,
66 @JsonProperty("blocked") boolean blocked
,
67 @JsonProperty("inboxPosition") Integer inboxPosition
,
68 @JsonProperty("archived") boolean archived
,
69 @JsonProperty("messageExpirationTime") int messageExpirationTime
,
70 @JsonProperty("active") boolean _ignored_active
72 this.groupId
= GroupId
.v1(groupId
);
73 this.expectedV2Id
= GroupId
.v2(expectedV2Id
);
75 this.members
.addAll(members
);
77 this.blocked
= blocked
;
78 this.inboxPosition
= inboxPosition
;
79 this.archived
= archived
;
80 this.messageExpirationTime
= messageExpirationTime
;
85 public GroupIdV1
getGroupId() {
89 @JsonProperty("groupId")
90 private byte[] getGroupIdJackson() {
91 return groupId
.serialize();
95 public GroupIdV2
getExpectedV2Id() {
96 if (expectedV2Id
== null) {
97 expectedV2Id
= GroupUtils
.getGroupIdV2(groupId
);
102 @JsonProperty("expectedV2Id")
103 private byte[] getExpectedV2IdJackson() {
104 return getExpectedV2Id().serialize();
108 public String
getTitle() {
113 public GroupInviteLinkUrl
getGroupInviteLink() {
118 public Set
<SignalServiceAddress
> getMembers() {
123 public boolean isBlocked() {
128 public void setBlocked(final boolean blocked
) {
129 this.blocked
= blocked
;
133 public int getMessageExpirationTime() {
134 return messageExpirationTime
;
137 public void addMembers(Collection
<SignalServiceAddress
> addresses
) {
138 for (SignalServiceAddress address
: addresses
) {
139 if (this.members
.contains(address
)) {
142 removeMember(address
);
143 this.members
.add(address
);
147 public void removeMember(SignalServiceAddress address
) {
148 this.members
.removeIf(member
-> member
.matches(address
));
151 private static final class JsonSignalServiceAddress
{
157 private String number
;
159 JsonSignalServiceAddress(@JsonProperty("uuid") final UUID uuid
, @JsonProperty("number") final String number
) {
161 this.number
= number
;
164 JsonSignalServiceAddress(SignalServiceAddress address
) {
165 this.uuid
= address
.getUuid().orNull();
166 this.number
= address
.getNumber().orNull();
169 SignalServiceAddress
toSignalServiceAddress() {
170 return new SignalServiceAddress(uuid
, number
);
174 private static class MembersSerializer
extends JsonSerializer
<Set
<SignalServiceAddress
>> {
177 public void serialize(
178 final Set
<SignalServiceAddress
> value
, final JsonGenerator jgen
, final SerializerProvider provider
179 ) throws IOException
{
180 jgen
.writeStartArray(value
.size());
181 for (SignalServiceAddress address
: value
) {
182 if (address
.getUuid().isPresent()) {
183 jgen
.writeObject(new JsonSignalServiceAddress(address
));
185 jgen
.writeString(address
.getNumber().get());
188 jgen
.writeEndArray();
192 private static class MembersDeserializer
extends JsonDeserializer
<Set
<SignalServiceAddress
>> {
195 public Set
<SignalServiceAddress
> deserialize(
196 JsonParser jsonParser
, DeserializationContext deserializationContext
197 ) throws IOException
{
198 Set
<SignalServiceAddress
> addresses
= new HashSet
<>();
199 JsonNode node
= jsonParser
.getCodec().readTree(jsonParser
);
200 for (JsonNode n
: node
) {
202 addresses
.add(new SignalServiceAddress(null, n
.textValue()));
204 JsonSignalServiceAddress address
= jsonProcessor
.treeToValue(n
, JsonSignalServiceAddress
.class);
205 addresses
.add(address
.toSignalServiceAddress());