]> nmode's Git Repositories - signal-cli/blobdiff - src/main/java/org/asamk/signal/storage/groups/GroupInfo.java
Store group member uuids in group store
[signal-cli] / src / main / java / org / asamk / signal / storage / groups / GroupInfo.java
index cb53d3af3a44ed275da71b5901417e6016138f5f..21ba910f485b80fc9773da05ca0c8fe5518d6cff 100644 (file)
@@ -2,15 +2,29 @@ package org.asamk.signal.storage.groups;
 
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
 
 import org.whispersystems.signalservice.api.push.SignalServiceAddress;
 
+import java.io.IOException;
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.Set;
+import java.util.UUID;
 
 public class GroupInfo {
 
+    private static final ObjectMapper jsonProcessor = new ObjectMapper();
+
     @JsonProperty
     public final byte[] groupId;
 
@@ -18,7 +32,9 @@ public class GroupInfo {
     public String name;
 
     @JsonProperty
-    public Set<String> members = new HashSet<>();
+    @JsonDeserialize(using = MembersDeserializer.class)
+    @JsonSerialize(using = MembersSerializer.class)
+    public Set<SignalServiceAddress> members = new HashSet<>();
     @JsonProperty
     public String color;
     @JsonProperty(defaultValue = "false")
@@ -38,7 +54,7 @@ public class GroupInfo {
         this.groupId = groupId;
     }
 
-    public GroupInfo(@JsonProperty("groupId") byte[] groupId, @JsonProperty("name") String name, @JsonProperty("members") Collection<String> members, @JsonProperty("avatarId") long avatarId, @JsonProperty("color") String color, @JsonProperty("blocked") boolean blocked, @JsonProperty("inboxPosition") Integer inboxPosition, @JsonProperty("archived") boolean archived) {
+    public GroupInfo(@JsonProperty("groupId") byte[] groupId, @JsonProperty("name") String name, @JsonProperty("members") Collection<SignalServiceAddress> members, @JsonProperty("avatarId") long avatarId, @JsonProperty("color") String color, @JsonProperty("blocked") boolean blocked, @JsonProperty("inboxPosition") Integer inboxPosition, @JsonProperty("archived") boolean archived) {
         this.groupId = groupId;
         this.name = name;
         this.members.addAll(members);
@@ -56,16 +72,108 @@ public class GroupInfo {
 
     @JsonIgnore
     public Set<SignalServiceAddress> getMembers() {
-        Set<SignalServiceAddress> addresses = new HashSet<>(members.size());
-        for (String member : members) {
-            addresses.add(new SignalServiceAddress(null, member));
-        }
-        return addresses;
+        return members;
     }
 
-    public void addMembers(Collection<SignalServiceAddress> members) {
+    @JsonIgnore
+    public Set<String> getMembersE164() {
+        Set<String> membersE164 = new HashSet<>();
         for (SignalServiceAddress member : members) {
-            this.members.add(member.getNumber().get());
+            if (!member.getNumber().isPresent()) {
+                continue;
+            }
+            membersE164.add(member.getNumber().get());
+        }
+        return membersE164;
+    }
+
+    @JsonIgnore
+    public Set<SignalServiceAddress> getMembersWithout(SignalServiceAddress address) {
+        Set<SignalServiceAddress> members = new HashSet<>(this.members.size());
+        for (SignalServiceAddress member : this.members) {
+            if (!member.matches(address)) {
+                members.add(member);
+            }
+        }
+        return members;
+    }
+
+    public void addMembers(Collection<SignalServiceAddress> addresses) {
+        for (SignalServiceAddress address : addresses) {
+            removeMember(address);
+            this.members.add(address);
+        }
+    }
+
+    public void removeMember(SignalServiceAddress address) {
+        this.members.removeIf(member -> member.matches(address));
+    }
+
+    @JsonIgnore
+    public boolean isMember(SignalServiceAddress address) {
+        for (SignalServiceAddress member : this.members) {
+            if (member.matches(address)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private static final class JsonSignalServiceAddress {
+
+        @JsonProperty
+        private UUID uuid;
+
+        @JsonProperty
+        private String number;
+
+        JsonSignalServiceAddress(@JsonProperty("uuid") final UUID uuid, @JsonProperty("number") final String number) {
+            this.uuid = uuid;
+            this.number = number;
+        }
+
+        JsonSignalServiceAddress(SignalServiceAddress address) {
+            this.uuid = address.getUuid().orNull();
+            this.number = address.getNumber().orNull();
+        }
+
+        SignalServiceAddress toSignalServiceAddress() {
+            return new SignalServiceAddress(uuid, number);
+        }
+    }
+
+    private static class MembersSerializer extends JsonSerializer<Set<SignalServiceAddress>> {
+
+        @Override
+        public void serialize(final Set<SignalServiceAddress> value, final JsonGenerator jgen, final SerializerProvider provider) throws IOException {
+            jgen.writeStartArray(value.size());
+            for (SignalServiceAddress address : value) {
+                if (address.getUuid().isPresent()) {
+                    jgen.writeObject(new JsonSignalServiceAddress(address));
+                } else {
+                    jgen.writeString(address.getNumber().get());
+                }
+            }
+            jgen.writeEndArray();
+        }
+    }
+
+    private static class MembersDeserializer extends JsonDeserializer<Set<SignalServiceAddress>> {
+
+        @Override
+        public Set<SignalServiceAddress> deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
+            Set<SignalServiceAddress> addresses = new HashSet<>();
+            JsonNode node = jsonParser.getCodec().readTree(jsonParser);
+            for (JsonNode n : node) {
+                if (n.isTextual()) {
+                    addresses.add(new SignalServiceAddress(null, n.textValue()));
+                } else {
+                    JsonSignalServiceAddress address = jsonProcessor.treeToValue(n, JsonSignalServiceAddress.class);
+                    addresses.add(address.toSignalServiceAddress());
+                }
+            }
+
+            return addresses;
         }
     }
 }